From 6da206b31442ce4cc7693a3550dcd45c2be5168e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Mar 2019 11:26:19 -0800 Subject: [PATCH 001/157] Add back in MSVC version check for LLVM --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 38ad31bde8ff6..4fc9fb8245abe 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 38ad31bde8ff681d862dc0f96930a5dd9b7a472e +Subproject commit 4fc9fb8245abe24680192535870c4522644a4212 From 02b008599ebe69d2d1b17018cee07e39347c1940 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 13 Nov 2018 13:42:05 -0800 Subject: [PATCH 002/157] appveyor: Use VS2017 for all our images Originally added in #55935 to test build times, this was reverted in #56201 due to a belief that it caused the exit code 259 spurious errors. We've since learned, however, that the 259 exit code is likely not related to this image update as we're getting it in a number of locations now. VS2017 looks like it may be required to compile LLVm in the near future, notably discovered by #58408 where we attempted to update LLVM. --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3a0cb8b4fceea..2862c240c277c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,7 @@ environment: + # This is required for at least an AArch64 compiler in one image, and is also + # going to soon be required for compiling LLVM. + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview # By default schannel checks revocation of certificates unlike some other SSL # backends, but we've historically had problems on CI where a revocation @@ -86,7 +89,6 @@ environment: DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 CI_JOB_NAME: dist-x86_64-msvc - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview - RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc From e969de88bb6121ccd99b97377a5fa04b3aaaae28 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 2 Mar 2019 17:17:08 +0100 Subject: [PATCH 003/157] Fix "Auto-hide item methods documentation" setting --- src/librustdoc/html/static/main.js | 69 ++++++++++++++++-------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1849e53d937ad..fef6910f40a57 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2077,16 +2077,22 @@ if (!DOMTokenList.prototype.remove) { } var toggle = createSimpleToggle(false); + var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false"; + var pageId = getPageId(); var func = function(e) { var next = e.nextElementSibling; if (!next) { return; } - if (hasClass(next, "docblock") || - (hasClass(next, "stability") && - hasClass(next.nextElementSibling, "docblock"))) { - insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); + if (hasClass(next, "docblock") === true || + (hasClass(next, "stability") === true && + hasClass(next.nextElementSibling, "docblock") === true)) { + var newToggle = toggle.cloneNode(true); + insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); + if (hideMethodDocs === true && hasClass(e, "method") === true) { + collapseDocs(newToggle, "hide", pageId); + } } }; @@ -2107,17 +2113,16 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("associatedconstant"), func); onEachLazy(document.getElementsByClassName("impl"), funcImpl); var impl_call = function() {}; - if (getCurrentValue("rustdoc-method-docs") !== "false") { + if (hideMethodDocs === true) { impl_call = function(e, newToggle, pageId) { if (e.id.match(/^impl(?:-\d+)?$/) === null) { // Automatically minimize all non-inherent impls - if (hasClass(e, "impl")) { + if (hasClass(e, "impl") === true) { collapseDocs(newToggle, "hide", pageId); } } }; } - var pageId = getPageId(); var newToggle = document.createElement("a"); newToggle.href = "javascript:void(0)"; newToggle.className = "collapse-toggle hidden-default collapsed"; @@ -2163,7 +2168,7 @@ if (!DOMTokenList.prototype.remove) { var inner_toggle = newToggle.cloneNode(true); inner_toggle.onclick = toggleClicked; e.insertBefore(inner_toggle, e.firstChild); - impl_call(e, inner_toggle, pageId); + impl_call(e.previousSibling, inner_toggle, pageId); } }); @@ -2265,30 +2270,6 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); - // In the search display, allows to switch between tabs. - function printTab(nb) { - if (nb === 0 || nb === 1 || nb === 2) { - currentTab = nb; - } - var nb_copy = nb; - onEachLazy(document.getElementById("titles").childNodes, function(elem) { - if (nb_copy === 0) { - addClass(elem, "selected"); - } else { - removeClass(elem, "selected"); - } - nb_copy -= 1; - }); - onEachLazy(document.getElementById("results").childNodes, function(elem) { - if (nb === 0) { - elem.style.display = ""; - } else { - elem.style.display = "none"; - } - nb -= 1; - }); - } - function createToggleWrapper(tog) { var span = document.createElement("span"); span.className = "toggle-label"; @@ -2374,6 +2355,30 @@ if (!DOMTokenList.prototype.remove) { }; }); + // In the search display, allows to switch between tabs. + function printTab(nb) { + if (nb === 0 || nb === 1 || nb === 2) { + currentTab = nb; + } + var nb_copy = nb; + onEachLazy(document.getElementById("titles").childNodes, function(elem) { + if (nb_copy === 0) { + addClass(elem, "selected"); + } else { + removeClass(elem, "selected"); + } + nb_copy -= 1; + }); + onEachLazy(document.getElementById("results").childNodes, function(elem) { + if (nb === 0) { + elem.style.display = ""; + } else { + elem.style.display = "none"; + } + nb -= 1; + }); + } + function putBackSearch(search_input) { if (search_input.value !== "") { addClass(main, "hidden"); From c82a42c155aa4b4825cb8dc21e9e498a752af13f Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Sun, 3 Mar 2019 19:47:17 +0000 Subject: [PATCH 004/157] Change `std::fs::copy` to use `copyfile` on MacOS and iOS --- src/libstd/fs.rs | 3 +- src/libstd/sys/unix/fs.rs | 87 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..3454f847ef414 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1581,7 +1581,8 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// `O_CLOEXEC` is set for returned file descriptors. /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate /// NTFS streams are copied but only the size of the main stream is returned by -/// this function. +/// this function. On MacOS, this function corresponds to `copyfile` with +/// `COPYFILE_ALL` /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 3b80b475a93db..7ff098bc9e123 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result { Ok(PathBuf::from(OsString::from_vec(buf))) } -#[cfg(not(any(target_os = "linux", target_os = "android")))] +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "macos", + target_os = "ios")))] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::fs::File; if !from.is_file() { @@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { writer.set_permissions(perm)?; Ok(written) } + +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn copy(from: &Path, to: &Path) -> io::Result { + const COPYFILE_ACL: u32 = 1 << 0; + const COPYFILE_STAT: u32 = 1 << 1; + const COPYFILE_XATTR: u32 = 1 << 2; + const COPYFILE_DATA: u32 = 1 << 3; + + const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL; + const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR; + const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA; + + const COPYFILE_STATE_COPIED: u32 = 8; + + #[allow(non_camel_case_types)] + type copyfile_state_t = *mut libc::c_void; + #[allow(non_camel_case_types)] + type copyfile_flags_t = u32; + + extern "C" { + fn copyfile( + from: *const libc::c_char, + to: *const libc::c_char, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> libc::c_int; + fn copyfile_state_alloc() -> copyfile_state_t; + fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int; + fn copyfile_state_get( + state: copyfile_state_t, + flag: u32, + dst: *mut libc::c_void, + ) -> libc::c_int; + } + + struct FreeOnDrop(copyfile_state_t); + impl Drop for FreeOnDrop { + fn drop(&mut self) { + // The code below ensures that `FreeOnDrop` is never a null pointer + unsafe { + // `copyfile_state_free` returns -1 if the `to` or `from` files + // cannot be closed. However, this is not considerd this an + // error. + copyfile_state_free(self.0); + } + } + } + + if !from.is_file() { + return Err(Error::new(ErrorKind::InvalidInput, + "the source path is not an existing regular file")) + } + + // We ensure that `FreeOnDrop` never contains a null pointer so it is + // always safe to call `copyfile_state_free` + let state = unsafe { + let state = copyfile_state_alloc(); + if state.is_null() { + return Err(crate::io::Error::last_os_error()); + } + FreeOnDrop(state) + }; + + cvt(unsafe { + copyfile( + cstr(from)?.as_ptr(), + cstr(to)?.as_ptr(), + state.0, + COPYFILE_ALL, + ) + })?; + + let mut bytes_copied: libc::off_t = 0; + cvt(unsafe { + copyfile_state_get( + state.0, + COPYFILE_STATE_COPIED, + &mut bytes_copied as *mut libc::off_t as *mut libc::c_void, + ) + })?; + Ok(bytes_copied as u64) +} From 0a991e424a794d0d556602e88cd2ebf511b05de7 Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Mon, 4 Mar 2019 12:35:46 +0000 Subject: [PATCH 005/157] Add test for the behaviour of `fs::copy` when `to` is a symlink --- src/libstd/fs.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 3454f847ef414..7b9b5d4de206c 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2837,6 +2837,26 @@ mod tests { assert_eq!(check!(out_path.metadata()).len(), copied_len); } + #[test] + fn copy_file_follows_dst_symlink() { + let tmp = tmpdir(); + if !got_symlink_permission(&tmp) { return }; + + let in_path = tmp.join("in.txt"); + let out_path = tmp.join("out.txt"); + let out_path_symlink = tmp.join("out_symlink.txt"); + + check!(fs::write(&in_path, "foo")); + check!(fs::write(&out_path, "bar")); + check!(symlink_file(&out_path, &out_path_symlink)); + + check!(fs::copy(&in_path, &out_path_symlink)); + + assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink()); + assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec()); + assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec()); + } + #[test] fn symlinks_work() { let tmpdir = tmpdir(); From 124ab2a4d87f2d10b88d668e35286af4c00ec12b Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Mon, 4 Mar 2019 12:53:54 +0000 Subject: [PATCH 006/157] Fix typo --- src/libstd/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 7b9b5d4de206c..a03f55424a9cd 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1582,7 +1582,7 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate /// NTFS streams are copied but only the size of the main stream is returned by /// this function. On MacOS, this function corresponds to `copyfile` with -/// `COPYFILE_ALL` +/// `COPYFILE_ALL`. /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior From 3f20a5dff7926da1b7bfe511cc26887ddf70c0b5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 18 Feb 2019 10:54:16 +0100 Subject: [PATCH 007/157] Optimize copying large ranges of undefmask blocks --- src/librustc/mir/interpret/allocation.rs | 45 ++++++++++++++++++++---- src/librustc_mir/interpret/memory.rs | 22 ++++++++++-- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index e96392edd64bf..06d5f27ccd744 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -613,7 +613,6 @@ impl DerefMut for Relocations { //////////////////////////////////////////////////////////////////////////////// type Block = u64; -const BLOCK_SIZE: u64 = 64; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct UndefMask { @@ -624,6 +623,8 @@ pub struct UndefMask { impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len}); impl UndefMask { + pub const BLOCK_SIZE: u64 = 64; + pub fn new(size: Size) -> Self { let mut m = UndefMask { blocks: vec![], @@ -643,6 +644,7 @@ impl UndefMask { return Err(self.len); } + // FIXME(oli-obk): optimize this for allocations larger than a block. let idx = (start.bytes()..end.bytes()) .map(|i| Size::from_bytes(i)) .find(|&i| !self.get(i)); @@ -662,8 +664,31 @@ impl UndefMask { } pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) { - for i in start.bytes()..end.bytes() { - self.set(Size::from_bytes(i), new_state); + let (blocka, bita) = bit_index(start); + let (blockb, bitb) = bit_index(end); + if blocka == blockb { + // within a single block + for i in bita .. bitb { + self.set_bit(blocka, i, new_state); + } + return; + } + // across block boundaries + for i in bita .. Self::BLOCK_SIZE as usize { + self.set_bit(blocka, i, new_state); + } + for i in 0 .. bitb { + self.set_bit(blockb, i, new_state); + } + // fill in all the other blocks (much faster than one bit at a time) + if new_state { + for block in (blocka + 1) .. blockb { + self.blocks[block] = 0xFFFF_FFFF_FFFF_FFFF; + } + } else { + for block in (blocka + 1) .. blockb { + self.blocks[block] = 0; + } } } @@ -676,6 +701,11 @@ impl UndefMask { #[inline] pub fn set(&mut self, i: Size, new_state: bool) { let (block, bit) = bit_index(i); + self.set_bit(block, bit, new_state); + } + + #[inline] + fn set_bit(&mut self, block: usize, bit: usize, new_state: bool) { if new_state { self.blocks[block] |= 1 << bit; } else { @@ -684,11 +714,12 @@ impl UndefMask { } pub fn grow(&mut self, amount: Size, new_state: bool) { - let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len.bytes(); + let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes(); if amount.bytes() > unused_trailing_bits { - let additional_blocks = amount.bytes() / BLOCK_SIZE + 1; + let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1; assert_eq!(additional_blocks as usize as u64, additional_blocks); self.blocks.extend( + // FIXME(oli-obk): optimize this by repeating `new_state as Block` iter::repeat(0).take(additional_blocks as usize), ); } @@ -701,8 +732,8 @@ impl UndefMask { #[inline] fn bit_index(bits: Size) -> (usize, usize) { let bits = bits.bytes(); - let a = bits / BLOCK_SIZE; - let b = bits % BLOCK_SIZE; + let a = bits / UndefMask::BLOCK_SIZE; + let b = bits % UndefMask::BLOCK_SIZE; assert_eq!(a as usize as u64, a); assert_eq!(b as usize as u64, b); (a as usize, b as usize) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 88b936afaa4c1..78668c5ad875e 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -20,7 +20,7 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, EvalResult, Scalar, EvalErrorKind, AllocKind, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck, + Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck, UndefMask, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -785,10 +785,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { assert_eq!(size.bytes() as usize as u64, size.bytes()); let undef_mask = self.get(src.alloc_id)?.undef_mask.clone(); + let get = |i| undef_mask.get(src.offset + Size::from_bytes(i)); let dest_allocation = self.get_mut(dest.alloc_id)?; + // an optimization where we can just overwrite an entire range of definedness bits if + // they are going to be uniformly `1` or `0`. + if size.bytes() * repeat > UndefMask::BLOCK_SIZE { + let first = undef_mask.get(src.offset); + // check that all bits are the same as the first bit + // FIXME(oli-obk): consider making this a function on `UndefMask` and optimize it, too + if (1..size.bytes()).all(|i| get(i) == first) { + dest_allocation.undef_mask.set_range( + dest.offset, + dest.offset + size * repeat, + first, + ); + return Ok(()) + } + } + + // the default path for i in 0..size.bytes() { - let defined = undef_mask.get(src.offset + Size::from_bytes(i)); + let defined = get(i); for j in 0..repeat { dest_allocation.undef_mask.set( From 1e3d1b65c500a33993462c84ecb80136d184acb2 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 18 Feb 2019 13:55:55 +0100 Subject: [PATCH 008/157] No magic numbers --- src/librustc/mir/interpret/allocation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 06d5f27ccd744..18880c551ed55 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -683,7 +683,7 @@ impl UndefMask { // fill in all the other blocks (much faster than one bit at a time) if new_state { for block in (blocka + 1) .. blockb { - self.blocks[block] = 0xFFFF_FFFF_FFFF_FFFF; + self.blocks[block] = u64::max_value(); } } else { for block in (blocka + 1) .. blockb { From aa8c48a2746e85b1a2e2ff53a34f30b81920fa5f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 19 Feb 2019 09:35:06 +0100 Subject: [PATCH 009/157] Don't try to copy relocations if there are none --- src/librustc_mir/interpret/memory.rs | 39 ++++++++++++++++------------ 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 78668c5ad875e..8cbc404e28b31 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -700,24 +700,29 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // relocations overlapping the edges; those would not be handled correctly). let relocations = { let relocations = self.get(src.alloc_id)?.relocations(self, src, size); - let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); - for i in 0..length { - new_relocations.extend( - relocations - .iter() - .map(|&(offset, reloc)| { - // compute offset for current repetition - let dest_offset = dest.offset + (i * size); - ( - // shift offsets from source allocation to destination allocation - offset + dest_offset - src.offset, - reloc, - ) - }) - ); - } + if relocations.is_empty() { + // nothing to copy, ignore even the `length` loop + Vec::new() + } else { + let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); + for i in 0..length { + new_relocations.extend( + relocations + .iter() + .map(|&(offset, reloc)| { + // compute offset for current repetition + let dest_offset = dest.offset + (i * size); + ( + // shift offsets from source allocation to destination allocation + offset + dest_offset - src.offset, + reloc, + ) + }) + ); + } - new_relocations + new_relocations + } }; let tcx = self.tcx.tcx; From d32b7e5b13ee833675c8fb3c905a4286690ceb15 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 19 Feb 2019 09:43:39 +0100 Subject: [PATCH 010/157] Test the `UndefMask` type --- src/test/run-pass-fulldeps/undef_mask.rs | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/run-pass-fulldeps/undef_mask.rs diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs new file mode 100644 index 0000000000000..37c44e2df6c5e --- /dev/null +++ b/src/test/run-pass-fulldeps/undef_mask.rs @@ -0,0 +1,26 @@ +// ignore-cross-compile +// ignore-stage1 + +#![feature(rustc_private)] + +extern crate rustc; + +use rustc::mir::interpret::UndefMask; +use rustc::ty::layout::Size; + +fn main() { + let mut mask = UndefMask::new(Size::from_bytes(500)); + assert!(!mask.get(Size::from_bytes(499))); + mask.set(Size::from_bytes(499), true); + assert!(mask.get(Size::from_bytes(499))); + mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true); + for i in 0..100 { + assert!(!mask.get(Size::from_bytes(i))); + } + for i in 100..256 { + assert!(mask.get(Size::from_bytes(i))); + } + for i in 256..499 { + assert!(!mask.get(Size::from_bytes(i))); + } +} From 4ded592f60c3f1a16db56fadcd7924121ed92ce8 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 19 Feb 2019 12:40:56 +0100 Subject: [PATCH 011/157] Use a more general approach for setting large definedness ranges --- src/librustc_mir/interpret/memory.rs | 70 ++++++++++++++++++---------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 8cbc404e28b31..6cbb611c1a3ec 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -20,7 +20,7 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, EvalResult, Scalar, EvalErrorKind, AllocKind, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck, UndefMask, + Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -789,38 +789,58 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // The bits have to be saved locally before writing to dest in case src and dest overlap. assert_eq!(size.bytes() as usize as u64, size.bytes()); - let undef_mask = self.get(src.alloc_id)?.undef_mask.clone(); - let get = |i| undef_mask.get(src.offset + Size::from_bytes(i)); - let dest_allocation = self.get_mut(dest.alloc_id)?; + let undef_mask = &self.get(src.alloc_id)?.undef_mask; + + // a precomputed cache for ranges of defined/undefined bits + // 0000010010001110 will become + // [5, 1, 2, 1, 3, 3, 1] + // where each element toggles the state + let mut ranges = smallvec::SmallVec::<[u64; 1]>::new(); + let first = undef_mask.get(src.offset); + let mut cur_len = 1; + let mut cur = first; + for i in 1..size.bytes() { + // FIXME: optimize to bitshift the current undef block's bits and read the top bit + if undef_mask.get(src.offset + Size::from_bytes(i)) == cur { + cur_len += 1; + } else { + ranges.push(cur_len); + cur_len = 1; + cur = !cur; + } + } + // now fill in all the data + let dest_allocation = self.get_mut(dest.alloc_id)?; // an optimization where we can just overwrite an entire range of definedness bits if // they are going to be uniformly `1` or `0`. - if size.bytes() * repeat > UndefMask::BLOCK_SIZE { - let first = undef_mask.get(src.offset); - // check that all bits are the same as the first bit - // FIXME(oli-obk): consider making this a function on `UndefMask` and optimize it, too - if (1..size.bytes()).all(|i| get(i) == first) { - dest_allocation.undef_mask.set_range( - dest.offset, - dest.offset + size * repeat, - first, - ); - return Ok(()) - } + if ranges.is_empty() { + dest_allocation.undef_mask.set_range( + dest.offset, + dest.offset + size * repeat, + first, + ); + return Ok(()) } - // the default path - for i in 0..size.bytes() { - let defined = get(i); - - for j in 0..repeat { - dest_allocation.undef_mask.set( - dest.offset + Size::from_bytes(i + (size.bytes() * j)), - defined + // remember to fill in the trailing bits + ranges.push(cur_len); + + for mut j in 0..repeat { + j *= size.bytes(); + j += dest.offset.bytes(); + let mut cur = first; + for range in &ranges { + let old_j = j; + j += range; + dest_allocation.undef_mask.set_range_inbounds( + Size::from_bytes(old_j), + Size::from_bytes(j), + cur, ); + cur = !cur; } } - Ok(()) } } From 60fde17a293ab94c56e415f5d5dd036527b4f201 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 20 Feb 2019 15:07:25 +0100 Subject: [PATCH 012/157] Use bit operations for setting large ranges of bits in a u64 --- src/librustc/mir/interpret/allocation.rs | 49 ++++++++++++++++-------- src/librustc_mir/interpret/memory.rs | 2 +- src/test/run-pass-fulldeps/undef_mask.rs | 2 +- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 18880c551ed55..004804f7c211e 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -100,8 +100,7 @@ impl AllocationExtra<(), ()> for () { impl Allocation { /// Creates a read-only allocation initialized by the given bytes pub fn from_bytes(slice: &[u8], align: Align, extra: Extra) -> Self { - let mut undef_mask = UndefMask::new(Size::ZERO); - undef_mask.grow(Size::from_bytes(slice.len() as u64), true); + let undef_mask = UndefMask::new(Size::from_bytes(slice.len() as u64), true); Self { bytes: slice.to_owned(), relocations: Relocations::new(), @@ -121,7 +120,7 @@ impl Allocation { Allocation { bytes: vec![0; size.bytes() as usize], relocations: Relocations::new(), - undef_mask: UndefMask::new(size), + undef_mask: UndefMask::new(size, false), align, mutability: Mutability::Mutable, extra, @@ -625,12 +624,12 @@ impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len}); impl UndefMask { pub const BLOCK_SIZE: u64 = 64; - pub fn new(size: Size) -> Self { + pub fn new(size: Size, state: bool) -> Self { let mut m = UndefMask { blocks: vec![], len: Size::ZERO, }; - m.grow(size, false); + m.grow(size, state); m } @@ -667,25 +666,40 @@ impl UndefMask { let (blocka, bita) = bit_index(start); let (blockb, bitb) = bit_index(end); if blocka == blockb { - // within a single block - for i in bita .. bitb { - self.set_bit(blocka, i, new_state); + // first set all bits but the first `bita` + // then unset the last `64 - bitb` bits + let range = if bitb == 0 { + u64::max_value() << bita + } else { + (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb)) + }; + if new_state { + self.blocks[blocka] |= range; + } else { + self.blocks[blocka] &= !range; } return; } // across block boundaries - for i in bita .. Self::BLOCK_SIZE as usize { - self.set_bit(blocka, i, new_state); - } - for i in 0 .. bitb { - self.set_bit(blockb, i, new_state); - } - // fill in all the other blocks (much faster than one bit at a time) if new_state { + // set bita..64 to 1 + self.blocks[blocka] |= u64::max_value() << bita; + // set 0..bitb to 1 + if bitb != 0 { + self.blocks[blockb] |= u64::max_value() >> (64 - bitb); + } + // fill in all the other blocks (much faster than one bit at a time) for block in (blocka + 1) .. blockb { self.blocks[block] = u64::max_value(); } } else { + // set bita..64 to 0 + self.blocks[blocka] &= !(u64::max_value() << bita); + // set 0..bitb to 0 + if bitb != 0 { + self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb)); + } + // fill in all the other blocks (much faster than one bit at a time) for block in (blocka + 1) .. blockb { self.blocks[block] = 0; } @@ -695,7 +709,7 @@ impl UndefMask { #[inline] pub fn get(&self, i: Size) -> bool { let (block, bit) = bit_index(i); - (self.blocks[block] & 1 << bit) != 0 + (self.blocks[block] & (1 << bit)) != 0 } #[inline] @@ -714,6 +728,9 @@ impl UndefMask { } pub fn grow(&mut self, amount: Size, new_state: bool) { + if amount.bytes() == 0 { + return; + } let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes(); if amount.bytes() > unused_trailing_bits { let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1; diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 6cbb611c1a3ec..fba0a9af21392 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -815,7 +815,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { // an optimization where we can just overwrite an entire range of definedness bits if // they are going to be uniformly `1` or `0`. if ranges.is_empty() { - dest_allocation.undef_mask.set_range( + dest_allocation.undef_mask.set_range_inbounds( dest.offset, dest.offset + size * repeat, first, diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs index 37c44e2df6c5e..cf6e6f7231638 100644 --- a/src/test/run-pass-fulldeps/undef_mask.rs +++ b/src/test/run-pass-fulldeps/undef_mask.rs @@ -9,7 +9,7 @@ use rustc::mir::interpret::UndefMask; use rustc::ty::layout::Size; fn main() { - let mut mask = UndefMask::new(Size::from_bytes(500)); + let mut mask = UndefMask::new(Size::from_bytes(500), false); assert!(!mask.get(Size::from_bytes(499))); mask.set(Size::from_bytes(499), true); assert!(mask.get(Size::from_bytes(499))); From 2b49ec0bb676f324806bb271f4115c3a1c0afaf3 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 09:58:47 +0100 Subject: [PATCH 013/157] Move alloc::prelude::* to alloc::prelude::v1, make alloc a subset of std This was one of the unresolved questions of https://github.com/rust-lang/rfcs/pull/2480. As the RFC says this is maybe not useful in the sense that we are unlikely to ever have a second version, but making the crate a true subset makes one less issue to think about if we stabilize it and later want to merge standard library crates and have Cargo feature flags to enable or disable parts of the `std` crate. See also discussion in https://github.com/rust-lang/rust/pull/58175 --- src/liballoc/prelude/mod.rs | 15 +++++++++++++++ src/liballoc/{prelude.rs => prelude/v1.rs} | 12 ++---------- 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 src/liballoc/prelude/mod.rs rename src/liballoc/{prelude.rs => prelude/v1.rs} (60%) diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs new file mode 100644 index 0000000000000..44a859d31ecb4 --- /dev/null +++ b/src/liballoc/prelude/mod.rs @@ -0,0 +1,15 @@ +//! The alloc Prelude +//! +//! The purpose of this module is to alleviate imports of commonly-used +//! items of the `alloc` crate by adding a glob import to the top of modules: +//! +//! ``` +//! # #![allow(unused_imports)] +//! # #![feature(alloc)] +//! extern crate alloc; +//! use alloc::prelude::v1::*; +//! ``` + +#![unstable(feature = "alloc", issue = "27783")] + +pub mod v1; diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude/v1.rs similarity index 60% rename from src/liballoc/prelude.rs rename to src/liballoc/prelude/v1.rs index 6767cf89f73ba..2df330d19f8ce 100644 --- a/src/liballoc/prelude.rs +++ b/src/liballoc/prelude/v1.rs @@ -1,14 +1,6 @@ -//! The alloc Prelude +//! The first version of the prelude of `alloc` crate. //! -//! The purpose of this module is to alleviate imports of commonly-used -//! items of the `alloc` crate by adding a glob import to the top of modules: -//! -//! ``` -//! # #![allow(unused_imports)] -//! # #![feature(alloc)] -//! extern crate alloc; -//! use alloc::prelude::*; -//! ``` +//! See the [module-level documentation](../index.html) for more. #![unstable(feature = "alloc", issue = "27783")] From 1243859d402427d90271d646968a6a4e5ad0052b Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 5 Mar 2019 13:43:48 +0000 Subject: [PATCH 014/157] core: ensure VaList passes improper_ctypes lint Ensure the core::ffi::VaList structure passes the improper_ctypes lint. --- src/libcore/ffi.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index d88793f2801e7..5cc9c25c21e0f 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -79,9 +79,9 @@ impl fmt::Debug for VaListImpl { all supported platforms", issue = "44930")] struct VaListImpl { - stack: *mut (), - gr_top: *mut (), - vr_top: *mut (), + stack: *mut c_void, + gr_top: *mut c_void, + vr_top: *mut c_void, gr_offs: i32, vr_offs: i32, } @@ -98,8 +98,8 @@ struct VaListImpl { gpr: u8, fpr: u8, reserved: u16, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// x86_64 ABI implementation of a `va_list`. @@ -113,8 +113,8 @@ struct VaListImpl { struct VaListImpl { gp_offset: i32, fp_offset: i32, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// A wrapper for a `va_list` From 5d1022ad7b82168aee243d2adcbd83d1e886586f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 11:47:52 +0100 Subject: [PATCH 015/157] Rename the feature gate for alloc::prelude MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to separate it from that of the crate. New tracking issue: https://github.com/rust-lang/rust/issues/58935 --- src/liballoc/prelude/mod.rs | 3 ++- src/liballoc/prelude/v1.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs index 44a859d31ecb4..33cc51d173203 100644 --- a/src/liballoc/prelude/mod.rs +++ b/src/liballoc/prelude/mod.rs @@ -6,10 +6,11 @@ //! ``` //! # #![allow(unused_imports)] //! # #![feature(alloc)] +//! #![feature(alloc_prelude)] //! extern crate alloc; //! use alloc::prelude::v1::*; //! ``` -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] pub mod v1; diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index 2df330d19f8ce..b6b01395ad632 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -2,10 +2,10 @@ //! //! See the [module-level documentation](../index.html) for more. -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; From 72958acd57fb32e0f8027c0d7e76c9a0c7f155d2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Mar 2019 11:47:06 -0800 Subject: [PATCH 016/157] std: Spin for a global malloc lock on wasm32 There's lots of comments in the code, but the main gist of this commit is that the acquisition of the global malloc lock on the `wasm32-unknown-unknown` target when threads are enabled will not spin on contention rather than block. --- src/libstd/sys/wasm/alloc.rs | 95 ++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs index b9098548b9c1e..c1af6ec12623c 100644 --- a/src/libstd/sys/wasm/alloc.rs +++ b/src/libstd/sys/wasm/alloc.rs @@ -49,7 +49,6 @@ unsafe impl GlobalAlloc for System { #[cfg(target_feature = "atomics")] mod lock { - use crate::arch::wasm32; use crate::sync::atomic::{AtomicI32, Ordering::SeqCst}; static LOCKED: AtomicI32 = AtomicI32::new(0); @@ -61,14 +60,76 @@ mod lock { if LOCKED.swap(1, SeqCst) == 0 { return DropLock } - unsafe { - let r = wasm32::i32_atomic_wait( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } + // Ok so here's where things get a little depressing. At this point + // in time we need to synchronously acquire a lock, but we're + // contending with some other thread. Typically we'd execute some + // form of `i32.atomic.wait` like so: + // + // unsafe { + // let r = core::arch::wasm32::i32_atomic_wait( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // expected value + // -1, // timeout + // ); + // debug_assert!(r == 0 || r == 1); + // } + // + // Unfortunately though in doing so we would cause issues for the + // main thread. The main thread in a web browser *cannot ever + // block*, no exceptions. This means that the main thread can't + // actually execute the `i32.atomic.wait` instruction. + // + // As a result if we want to work within the context of browsers we + // need to figure out some sort of allocation scheme for the main + // thread where when there's contention on the global malloc lock we + // do... something. + // + // Possible ideas include: + // + // 1. Attempt to acquire the global lock. If it fails, fall back to + // memory allocation via `memory.grow`. Later just ... somehow + // ... inject this raw page back into the main allocator as it + // gets sliced up over time. This strategy has the downside of + // forcing allocation of a page to happen whenever the main + // thread contents with other threads, which is unfortunate. + // + // 2. Maintain a form of "two level" allocator scheme where the main + // thread has its own allocator. Somehow this allocator would + // also be balanced with a global allocator, not only to have + // allocations cross between threads but also to ensure that the + // two allocators stay "balanced" in terms of free'd memory and + // such. This, however, seems significantly complicated. + // + // Out of a lack of other ideas, the current strategy implemented + // here is to simply spin. Typical spin loop algorithms have some + // form of "hint" here to the CPU that it's what we're doing to + // ensure that the CPU doesn't get too hot, but wasm doesn't have + // such an instruction. + // + // To be clear, spinning here is not a great solution. + // Another thread with the lock may take quite a long time to wake + // up. For example it could be in `memory.grow` or it could be + // evicted from the CPU for a timeslice like 10ms. For these periods + // of time our thread will "helpfully" sit here and eat CPU time + // until it itself is evicted or the lock holder finishes. This + // means we're just burning and wasting CPU time to no one's + // benefit. + // + // Spinning does have the nice properties, though, of being + // semantically correct, being fair to all threads for memory + // allocation, and being simple enough to implement. + // + // This will surely (hopefully) be replaced in the future with a + // real memory allocator that can handle the restriction of the main + // thread. + // + // + // FIXME: We can also possibly add an optimization here to detect + // when a thread is the main thread or not and block on all + // non-main-thread threads. Currently, however, we have no way + // of knowing which wasm thread is on the browser main thread, but + // if we could figure out we could at least somewhat mitigate the + // cost of this spinning. } } @@ -76,12 +137,16 @@ mod lock { fn drop(&mut self) { let r = LOCKED.swap(0, SeqCst); debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic_notify( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } + + // Note that due to the above logic we don't actually need to wake + // anyone up, but if we did it'd likely look something like this: + // + // unsafe { + // core::arch::wasm32::atomic_notify( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // only one thread + // ); + // } } } } From 710988ad603c52657c72a7f1028415e3e244a97c Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Tue, 5 Mar 2019 23:28:15 +0800 Subject: [PATCH 017/157] MIPS: add r6 support MIPS r6 is quite different with the previous version. It use some new target triples: mipsisa32r6-unknown-linux-gnu mipsisa32r6el-unknown-linux-gnu mipsisa64r6-unknown-linux-gnuabi64 mipsisa64r6el-unknown-linux-gnuabi64 This patch has been tested with Debian Port for mips64r6el, and the support of these triples also is included in llvm: https://reviews.llvm.org/rGe58c45a695f39004710b6ce940d489fee800dbd3 --- .../spec/mipsisa32r6_unknown_linux_gnu.rs | 23 ++++++++++++++++++ .../spec/mipsisa32r6el_unknown_linux_gnu.rs | 24 +++++++++++++++++++ .../mipsisa64r6_unknown_linux_gnuabi64.rs | 24 +++++++++++++++++++ .../mipsisa64r6el_unknown_linux_gnuabi64.rs | 24 +++++++++++++++++++ src/librustc_target/spec/mod.rs | 4 ++++ src/tools/build-manifest/src/main.rs | 8 +++++++ src/tools/compiletest/src/util.rs | 8 +++++++ 7 files changed, 115 insertions(+) create mode 100644 src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs create mode 100644 src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs create mode 100644 src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs create mode 100644 src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f47291458492e --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -0,0 +1,23 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f4f98d33571f0 --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..7faed3adc79cc --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..58a814a759eb8 --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index bef2afc7b6292..1020464ca0b06 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -335,6 +335,10 @@ supported_targets! { ("mips-unknown-linux-gnu", mips_unknown_linux_gnu), ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64), ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64), + ("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu), + ("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu), + ("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64), + ("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64), ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8d87c404d0b28..6eb12ea016186 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -23,6 +23,10 @@ static HOSTS: &'static [&'static str] = &[ "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", @@ -77,6 +81,10 @@ static TARGETS: &'static [&'static str] = &[ "mips-unknown-linux-musl", "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "nvptx64-nvidia-cuda", diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 240287fa248bd..3533dcdc988a1 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -49,7 +49,15 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("mips64", "mips64"), ("mips64el", "mips64"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("mipsel", "mips"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("msp430", "msp430"), ("powerpc", "powerpc"), ("powerpc64", "powerpc64"), From 1879d17f082e58500c84529815a2a8ba955af999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 31 Jan 2019 23:11:29 +0100 Subject: [PATCH 018/157] Only insert nodes which changes lint levels in the LintLevelMap --- src/librustc/hir/map/mod.rs | 1 + src/librustc/lint/levels.rs | 7 ++-- src/librustc/lint/mod.rs | 21 ++++++++--- src/librustc/ty/context.rs | 60 +++++++++++++++++++------------ src/librustc_mir/build/scope.rs | 30 ++++++++++------ src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/cx/mod.rs | 41 ++------------------- 8 files changed, 80 insertions(+), 84 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 21a9ed5ebe03a..da1c541019c5d 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1033,6 +1033,7 @@ impl<'hir> Map<'hir> { pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { self.read(id); // reveals attributes on the node let attrs = match self.find(id) { + Some(Node::Local(l)) => Some(&l.attrs[..]), Some(Node::Item(i)) => Some(&i.attrs[..]), Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]), Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]), diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 924aa3fde0a08..3c6635c034131 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -157,6 +157,7 @@ pub struct LintLevelsBuilder<'a> { pub struct BuilderPush { prev: u32, + pub(super) changed: bool, } impl<'a> LintLevelsBuilder<'a> { @@ -454,6 +455,7 @@ impl<'a> LintLevelsBuilder<'a> { BuilderPush { prev: prev, + changed: prev != self.cur, } } @@ -512,11 +514,6 @@ impl LintLevelMap { self.sets.get_lint_level(lint, *idx, None, session) }) } - - /// Returns if this `id` has lint level information. - pub fn lint_level_set(&self, id: HirId) -> Option { - self.id_to_set.get(&id).cloned() - } } impl<'a> HashStable> for LintLevelMap { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 496ff568b31b4..b3fc5612ba547 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -721,6 +721,16 @@ pub fn struct_lint_level<'a>(sess: &'a Session, return err } +pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { + let attrs = tcx.hir().attrs_by_hir_id(id); + for attr in attrs { + if Level::from_str(&attr.name().as_str()).is_some() { + true; + } + } + false +} + fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) -> Lrc { @@ -731,9 +741,10 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) }; let krate = tcx.hir().krate(); - builder.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |builder| { - intravisit::walk_crate(builder, krate); - }); + let push = builder.levels.push(&krate.attrs); + builder.levels.register_id(hir::CRATE_HIR_ID); + intravisit::walk_crate(&mut builder, krate); + builder.levels.pop(push); Lrc::new(builder.levels.build_map()) } @@ -751,7 +762,9 @@ impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> { where F: FnOnce(&mut Self) { let push = self.levels.push(attrs); - self.levels.register_id(id); + if push.changed { + self.levels.register_id(id); + } f(self); self.levels.pop(push); } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3c63dcb9ef307..3f7018ed919cd 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2856,30 +2856,44 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { err.emit() } - pub fn lint_level_at_node(self, lint: &'static Lint, mut id: hir::HirId) - -> (lint::Level, lint::LintSource) - { - // Right now we insert a `with_ignore` node in the dep graph here to - // ignore the fact that `lint_levels` below depends on the entire crate. - // For now this'll prevent false positives of recompiling too much when - // anything changes. - // - // Once red/green incremental compilation lands we should be able to - // remove this because while the crate changes often the lint level map - // will change rarely. - self.dep_graph.with_ignore(|| { - let sets = self.lint_levels(LOCAL_CRATE); - loop { - if let Some(pair) = sets.level_and_source(lint, id, self.sess) { - return pair - } - let next = self.hir().get_parent_node_by_hir_id(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; + /// Walks upwards from `id` to find a node which might change lint levels with attributes. + /// It stops at `bound` and just returns it if reached. + pub fn maybe_lint_level_root_bounded( + self, + mut id: hir::HirId, + bound: hir::HirId, + ) -> hir::HirId { + loop { + if id == bound { + return bound; } - }) + if lint::maybe_lint_level_root(self, id) { + return id; + } + let next = self.hir().get_parent_node_by_hir_id(id); + if next == id { + bug!("lint traversal reached the root of the crate"); + } + id = next; + } + } + + pub fn lint_level_at_node( + self, + lint: &'static Lint, + mut id: hir::HirId + ) -> (lint::Level, lint::LintSource) { + let sets = self.lint_levels(LOCAL_CRATE); + loop { + if let Some(pair) = sets.level_and_source(lint, id, self.sess) { + return pair + } + let next = self.hir().get_parent_node_by_hir_id(id); + if next == id { + bug!("lint traversal reached the root of the crate"); + } + id = next; + } } pub fn struct_span_lint_hir>(self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 4189e3e7ddbb6..4aa463b37ab77 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -82,7 +82,6 @@ use crate::hair::LintLevel; use rustc::middle::region; use rustc::ty::Ty; use rustc::hir; -use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::*; use syntax_pos::{Span}; use rustc_data_structures::fx::FxHashMap; @@ -309,16 +308,25 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_scope = self.source_scope; let tcx = self.hir.tcx(); if let LintLevel::Explicit(current_hir_id) = lint_level { - let same_lint_scopes = tcx.dep_graph.with_ignore(|| { - let sets = tcx.lint_levels(LOCAL_CRATE); - let parent_hir_id = self.source_scope_local_data[source_scope].lint_root; - sets.lint_level_set(parent_hir_id) == sets.lint_level_set(current_hir_id) - }); - - if !same_lint_scopes { - self.source_scope = - self.new_source_scope(region_scope.1.span, lint_level, - None); + // Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound + // to avoid adding Hir dependences on our parents. + // We estimate the true lint roots here to avoid creating a lot of source scopes. + + let parent_root = tcx.maybe_lint_level_root_bounded( + self.source_scope_local_data[source_scope].lint_root, + self.hir.root_lint_level, + ); + let current_root = tcx.maybe_lint_level_root_bounded( + current_hir_id, + self.hir.root_lint_level + ); + + if parent_root != current_root { + self.source_scope = self.new_source_scope( + region_scope.1.span, + LintLevel::Explicit(current_root), + None + ); } } self.push_scope(region_scope); diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index f58e61915e8c9..17fab6c5ddcff 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -103,7 +103,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }, pattern, initializer: local.init.to_ref(), - lint_level: cx.lint_level_of(local.hir_id), + lint_level: LintLevel::Explicit(local.hir_id), }, opt_destruction_scope: opt_dxn_ext, span: stmt_span, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 65cd9f7103d68..1591fa318cae8 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -45,7 +45,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::Scope { region_scope: expr_scope, value: expr.to_ref(), - lint_level: cx.lint_level_of(self.hir_id), + lint_level: LintLevel::Explicit(self.hir_id), }, }; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 8b16eeeea23c0..c0f3989b4ba97 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -6,7 +6,7 @@ use crate::hair::*; use crate::hair::util::UserAnnotatedTyHelpers; use rustc_data_structures::indexed_vec::Idx; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::DefId; use rustc::hir::Node; use rustc::middle::region; use rustc::infer::InferCtxt; @@ -76,11 +76,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { // Constants always need overflow checks. check_overflow |= constness == hir::Constness::Const; - let lint_level = lint_level_for_hir_id(tcx, src_id); Cx { tcx, infcx, - root_lint_level: lint_level, + root_lint_level: src_id, param_env: tcx.param_env(src_def_id), identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id), region_scope_tree: tcx.region_scope_tree(src_def_id), @@ -197,18 +196,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { ty.needs_drop(self.tcx.global_tcx(), param_env) } - fn lint_level_of(&self, hir_id: hir::HirId) -> LintLevel { - let has_lint_level = self.tcx.dep_graph.with_ignore(|| { - self.tcx.lint_levels(LOCAL_CRATE).lint_level_set(hir_id).is_some() - }); - - if has_lint_level { - LintLevel::Explicit(hir_id) - } else { - LintLevel::Inherited - } - } - pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx } @@ -236,30 +223,6 @@ impl UserAnnotatedTyHelpers<'gcx, 'tcx> for Cx<'_, 'gcx, 'tcx> { } } -fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: hir::HirId) -> hir::HirId { - // Right now we insert a `with_ignore` node in the dep graph here to - // ignore the fact that `lint_levels` below depends on the entire crate. - // For now this'll prevent false positives of recompiling too much when - // anything changes. - // - // Once red/green incremental compilation lands we should be able to - // remove this because while the crate changes often the lint level map - // will change rarely. - tcx.dep_graph.with_ignore(|| { - let sets = tcx.lint_levels(LOCAL_CRATE); - loop { - if sets.lint_level_set(id).is_some() { - return id - } - let next = tcx.hir().get_parent_node_by_hir_id(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; - } - }) -} - mod block; mod expr; mod to_ref; From f07ce55d0f75d7a76c20e58e3639cdffbe770aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 5 Mar 2019 19:39:34 +0100 Subject: [PATCH 019/157] Add `return` --- src/librustc/lint/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index b3fc5612ba547..c01b0ae2ccc1d 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -725,7 +725,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { let attrs = tcx.hir().attrs_by_hir_id(id); for attr in attrs { if Level::from_str(&attr.name().as_str()).is_some() { - true; + return true; } } false From 67eabc6bec67e1953cb944f0654fada3151b7e21 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 5 Mar 2019 13:32:41 -0800 Subject: [PATCH 020/157] SGX target: Expose thread id function in os module --- src/libstd/os/fortanix_sgx/mod.rs | 5 +++++ src/libstd/sys/sgx/abi/thread.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index bca22e717d724..4e30b1edd15e8 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -43,3 +43,8 @@ pub mod mem { } pub use crate::sys::ext::{io, arch, ffi}; + +/// Functions for querying thread-related information. +pub mod thread { + pub use crate::sys::abi::thread::current; +} diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs index 86fe09d003520..c17fa2d00159e 100644 --- a/src/libstd/sys/sgx/abi/thread.rs +++ b/src/libstd/sys/sgx/abi/thread.rs @@ -4,6 +4,7 @@ use fortanix_sgx_abi::Tcs; /// all currently running threads in the enclave, and it is guaranteed to be /// constant for the lifetime of the thread. More specifically for SGX, there /// is a one-to-one correspondence of the ID to the address of the TCS. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn current() -> Tcs { extern "C" { fn get_tcs_addr() -> Tcs; } unsafe { get_tcs_addr() } From 876258b0fa31fc1d1a79ddc0e5a0c9c5f0e8f85b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 6 Mar 2019 19:46:33 +0100 Subject: [PATCH 021/157] Default to integrated `rust-lld` linker for UEFI targets --- src/librustc_target/spec/uefi_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index 631966c09a498..956767a22a0e1 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -59,7 +59,7 @@ pub fn opts() -> TargetOptions { singlethread: true, emit_debug_gdb_scripts: false, - linker: Some("lld-link".to_string()), + linker: Some("rust-lld".to_string()), lld_flavor: LldFlavor::Link, pre_link_args, From ec91f26442aaf51ececcb054f5a4b92f7f5c0615 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 18:38:49 -0800 Subject: [PATCH 022/157] Fix SGX implementations of read/write_vectored. --- src/libstd/sys/sgx/net.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index ab8b2681393f8..cea723f6e48e1 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -103,24 +103,22 @@ impl TcpStream { self.inner.inner.read(buf) } - pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result { - let buf = match buf.get_mut(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.read(buf) + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + match bufs.iter_mut().find(|b| !b.is_empty()) { + Some(buf) => self.read(buf), + None => Ok(0), + } } pub fn write(&self, buf: &[u8]) -> io::Result { self.inner.inner.write(buf) } - pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result { - let buf = match buf.get(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.write(buf) + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + match bufs.iter().find(|b| !b.is_empty()) { + Some(buf) => self.write(buf), + None => Ok(0), + } } pub fn peer_addr(&self) -> io::Result { From ab8e1d264e6722169d25d3f52ac2e8de172e205d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 19:31:58 -0800 Subject: [PATCH 023/157] Always call read/write from default vectored io methods --- src/libstd/io/mod.rs | 40 +++++++++++++++++++++++---------- src/libstd/sys/redox/net/tcp.rs | 10 ++------- src/libstd/sys/sgx/net.rs | 10 ++------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e3e2754a7aa09..1a2152a79af5a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -390,6 +390,28 @@ fn read_to_end_with_reservation(r: &mut R, ret } +pub(crate) fn default_read_vectored(read: F, bufs: &mut [IoVecMut<'_>]) -> Result +where + F: FnOnce(&mut [u8]) -> Result +{ + let buf = bufs + .iter_mut() + .find(|b| !b.is_empty()) + .map_or(&mut [][..], |b| &mut **b); + read(buf) +} + +pub(crate) fn default_write_vectored(write: F, bufs: &[IoVec<'_>]) -> Result +where + F: FnOnce(&[u8]) -> Result +{ + let buf = bufs + .iter() + .find(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); + write(buf) +} + /// The `Read` trait allows for reading bytes from a source. /// /// Implementors of the `Read` trait are called 'readers'. @@ -528,14 +550,11 @@ pub trait Read { /// written to possibly being only partially filled. This method must behave /// as a single call to `read` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `read`. + /// The default implementation calls `read` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + default_read_vectored(|b| self.read(b), bufs) } /// Determines if this `Read`er can work with buffers of uninitialized @@ -1107,14 +1126,11 @@ pub trait Write { /// read from possibly being only partially consumed. This method must /// behave as a call to `write` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `write`. + /// The default implementation calls `write` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + default_write_vectored(|b| self.write(b), bufs) } /// Flush this output stream, ensuring that all intermediately buffered diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index 5081c3de73c5a..3f2f6166a791a 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -35,10 +35,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> Result { @@ -46,10 +43,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn take_error(&self) -> Result> { diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index cea723f6e48e1..6021020e6f03c 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -104,10 +104,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> io::Result { @@ -115,10 +112,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn peer_addr(&self) -> io::Result { From 90ae8746709df0c09f63ebaff480b82205592b53 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Tue, 5 Mar 2019 17:43:30 -0700 Subject: [PATCH 024/157] add release notes for PR #56243 Fixes #58907 --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 4cda02c5c2ebe..a49e072e9eaa7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -110,8 +110,11 @@ Compatibility Notes methods instead. - The `Error::cause` method has been deprecated in favor of `Error::source` which supports downcasting. +- [Libtest no longer creates a new thread for each test when + `--test-threads=1`. It also runs the tests in deterministic order][56243] [55982]: https://github.com/rust-lang/rust/pull/55982/ +[56243]: https://github.com/rust-lang/rust/pull/56243 [56303]: https://github.com/rust-lang/rust/pull/56303/ [56351]: https://github.com/rust-lang/rust/pull/56351/ [56362]: https://github.com/rust-lang/rust/pull/56362 From bd2e12609f190e7bf206dac2de2d68dbb4b1b5e6 Mon Sep 17 00:00:00 2001 From: Dirk Leifeld Date: Sat, 9 Mar 2019 19:16:54 +0100 Subject: [PATCH 025/157] Revert "Revert "Add clamp functions"" --- src/libcore/cmp.rs | 26 ++++++++++++++++++++++++++ src/libstd/f32.rs | 20 ++++++++++++++++++++ src/libstd/f64.rs | 20 ++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 81fcdeee12d29..259135b9ca0ab 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -567,6 +567,32 @@ pub trait Ord: Eq + PartialOrd { where Self: Sized { if self <= other { self } else { other } } + + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this will return self. Panics if min > max. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp)] + /// + /// assert!((-3).clamp(-2, 1) == -2); + /// assert!(0.clamp(-2, 1) == 0); + /// assert!(2.clamp(-2, 1) == 1); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + fn clamp(self, min: Self, max: Self) -> Self + where Self: Sized { + assert!(min <= max); + if self < min { + min + } + else if self > max { + max + } else { + self + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index cb1f93581775c..df4dc2c779125 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -956,6 +956,26 @@ impl f32 { pub fn atanh(self) -> f32 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + /// + /// # Examples + /// + /// ``` + /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32); + /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32); + /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + #[inline] + pub fn clamp(self, min: f32, max: f32) -> f32 { + assert!(min <= max); + let mut x = self; + if x < min { x = min; } + if x > max { x = max; } + x + } + } #[cfg(test)] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 7fa7b80751938..00e7f27912817 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -878,6 +878,26 @@ impl f64 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } + /// Returns max if self is greater than max, and min if self is less than min. + /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + /// + /// # Examples + /// + /// ``` + /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64); + /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64); + /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64); + /// ``` + #[unstable(feature = "clamp", issue = "44095")] + #[inline] + pub fn clamp(self, min: f64, max: f64) -> f64 { + assert!(min <= max); + let mut x = self; + if x < min { x = min; } + if x > max { x = max; } + x + } + // Solaris/Illumos requires a wrapper around log, log2, and log10 functions // because of their non-standard behavior (e.g., log(-n) returns -Inf instead // of expected NaN). From 6041ec3b788a519ab740925c6b1c2f0ac19ad17d Mon Sep 17 00:00:00 2001 From: Dirk Leifeld Date: Sat, 9 Mar 2019 20:10:48 +0100 Subject: [PATCH 026/157] add feature clamp --- src/libstd/f32.rs | 1 + src/libstd/f64.rs | 1 + src/libstd/lib.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index df4dc2c779125..d158a6a5bccc8 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -962,6 +962,7 @@ impl f32 { /// # Examples /// /// ``` + /// #![feature(clamp)] /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32); /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32); /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32); diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 00e7f27912817..5be0cfa9b8f0a 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -884,6 +884,7 @@ impl f64 { /// # Examples /// /// ``` + /// #![feature(clamp)] /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64); /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64); /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 6dd3a6cc0fdbd..1c4918de42882 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -240,6 +240,7 @@ #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] #![feature(checked_duration_since)] +#![feature(clamp)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] #![feature(const_cstr_unchecked)] From a4ea08420cde12ea0943cafb1505e512c5820f70 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 8 Mar 2019 21:12:12 -0800 Subject: [PATCH 027/157] Avoid some common false positives in intra doc link checking --- src/librustdoc/passes/collect_intra_doc_links.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c346714ab485a..c3d2e63319a95 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -291,6 +291,12 @@ impl<'a, 'tcx, 'rcx> DocFolder for LinkCollector<'a, 'tcx, 'rcx> { if ori_link.contains('/') { continue; } + + // [] is mostly likely not supposed to be a link + if ori_link.is_empty() { + continue; + } + let link = ori_link.replace("`", ""); let (def, fragment) = { let mut kind = PathKind::Unknown; From 3a83cb2c9ba2acca0577a5f4a092d7fc5b243faf Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 9 Mar 2019 03:39:23 +0000 Subject: [PATCH 028/157] Fix ICE in MIR pretty printing A `Def::Variant` should be considered as a function in mir pretty printing. Each variant has a constructor that we must print. Given the following enum definition: ``` pub enum TestMe { X(usize), } ``` We will need to generate a constructor for the variant `X` with a signature that looks something like the following: ``` fn TestMe::X(_1: usize) -> TestMe; ``` --- src/librustc_mir/util/pretty.rs | 4 +++- src/test/mir-opt/unusual-item-types.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c3fbee3a2a6e5..af49f61ae86c7 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,4 +1,5 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def::CtorKind; use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; @@ -597,7 +598,8 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()); let is_function = match descr { - Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true, + Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) | + Some(Def::StructCtor(_, CtorKind::Fn)) => true, _ => tcx.is_closure(src.def_id()), }; match (descr, src.promoted) { diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index fe85baa048e39..ced30381fda68 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -7,11 +7,18 @@ impl A { const ASSOCIATED_CONSTANT: i32 = 2; } +// See #59021 +enum Test { + X(usize), + Y { a: usize }, +} + enum E { V = 5, } fn main() { + let f = Test::X as fn(usize) -> Test; let v = Vec::::new(); } @@ -64,3 +71,14 @@ fn main() { // _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5]; // } // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir + +// START rustc.Test-X.mir_map.0.mir +// fn Test::X(_1: usize) -> Test { +// let mut _0: Test; +// +// bb0: { +// _0 = Test::X(move _1,); +// return; +// } +// } +// END rustc.Test-X.mir_map.0.mir From 4c8cc141863274683681a6fa3d5d4e0230780c66 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 13 Feb 2019 08:13:30 -0500 Subject: [PATCH 029/157] Replace TimeLine with SelfProfiler --- src/librustc/lib.rs | 1 - src/librustc/util/profiling.rs | 31 ++- src/librustc/util/time_graph.rs | 268 ----------------------- src/librustc_codegen_llvm/back/lto.rs | 44 ++-- src/librustc_codegen_llvm/back/write.rs | 58 ++--- src/librustc_codegen_llvm/lib.rs | 21 +- src/librustc_codegen_ssa/back/lto.rs | 5 +- src/librustc_codegen_ssa/back/write.rs | 113 ++++++---- src/librustc_codegen_ssa/base.rs | 27 +-- src/librustc_codegen_ssa/traits/write.rs | 6 - src/librustc_interface/passes.rs | 12 +- src/librustc_typeck/lib.rs | 4 +- 12 files changed, 155 insertions(+), 435 deletions(-) delete mode 100644 src/librustc/util/time_graph.rs diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 6adfaa53946ac..681dffc0116e3 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -136,7 +136,6 @@ pub mod util { pub mod common; pub mod ppaux; pub mod nodemap; - pub mod time_graph; pub mod profiling; pub mod bug; } diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index c134d48f987be..2739a30a29135 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fs; use std::io::{BufWriter, Write}; use std::mem; @@ -20,12 +21,12 @@ pub enum ProfileCategory { Other, } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum ProfilerEvent { QueryStart { query_name: &'static str, category: ProfileCategory, time: u64 }, QueryEnd { query_name: &'static str, category: ProfileCategory, time: u64 }, - GenericActivityStart { category: ProfileCategory, time: u64 }, - GenericActivityEnd { category: ProfileCategory, time: u64 }, + GenericActivityStart { category: ProfileCategory, label: Cow<'static, str>, time: u64 }, + GenericActivityEnd { category: ProfileCategory, label: Cow<'static, str>, time: u64 }, IncrementalLoadResultStart { query_name: &'static str, time: u64 }, IncrementalLoadResultEnd { query_name: &'static str, time: u64 }, QueryCacheHit { query_name: &'static str, category: ProfileCategory, time: u64 }, @@ -75,17 +76,27 @@ impl SelfProfiler { } #[inline] - pub fn start_activity(&mut self, category: ProfileCategory) { + pub fn start_activity( + &mut self, + category: ProfileCategory, + label: impl Into>, + ) { self.record(ProfilerEvent::GenericActivityStart { category, + label: label.into(), time: self.get_time_from_start(), }) } #[inline] - pub fn end_activity(&mut self, category: ProfileCategory) { + pub fn end_activity( + &mut self, + category: ProfileCategory, + label: impl Into>, + ) { self.record(ProfilerEvent::GenericActivityEnd { category, + label: label.into(), time: self.get_time_from_start(), }) } @@ -273,11 +284,12 @@ impl SelfProfiler { nanos, thread_id, ).unwrap(), - GenericActivityStart { category, time: _ } => + GenericActivityStart { category, label, time: _ } => write!(file, "{{ \"GenericActivityStart\": {{\ \"category\": \"{:?}\",\ + \"label\": \"{}\",\ \"time\": {{\ \"secs\": {},\ \"nanos\": {}\ @@ -286,15 +298,17 @@ impl SelfProfiler { }}\ }}", category, + label, secs, nanos, thread_id, ).unwrap(), - GenericActivityEnd { category, time: _ } => + GenericActivityEnd { category, label, time: _ } => write!(file, "{{\ \"GenericActivityEnd\": {{\ \"category\": \"{:?}\",\ + \"label\": \"{}\",\ \"time\": {{\ \"secs\": {},\ \"nanos\": {}\ @@ -303,6 +317,7 @@ impl SelfProfiler { }}\ }}", category, + label, secs, nanos, thread_id, @@ -418,7 +433,7 @@ impl SelfProfiler { secs, nanos, thread_id, - ).unwrap() + ).unwrap(), } } } diff --git a/src/librustc/util/time_graph.rs b/src/librustc/util/time_graph.rs deleted file mode 100644 index 4dd383fd234ac..0000000000000 --- a/src/librustc/util/time_graph.rs +++ /dev/null @@ -1,268 +0,0 @@ -use rustc_data_structures::fx::FxHashMap; -use std::fs::File; -use std::io::prelude::*; -use std::marker::PhantomData; -use std::mem; -use std::sync::{Arc, Mutex}; -use std::time::Instant; - -const OUTPUT_WIDTH_IN_PX: u64 = 1000; -const TIME_LINE_HEIGHT_IN_PX: u64 = 20; -const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30; - -#[derive(Clone)] -struct Timing { - start: Instant, - end: Instant, - work_package_kind: WorkPackageKind, - name: String, - events: Vec<(String, Instant)>, -} - -#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)] -pub struct TimelineId(pub usize); - -#[derive(Clone)] -struct PerThread { - timings: Vec, - open_work_package: Option<(Instant, WorkPackageKind, String)>, -} - -#[derive(Clone)] -pub struct TimeGraph { - data: Arc>>, -} - -#[derive(Clone, Copy)] -pub struct WorkPackageKind(pub &'static [&'static str]); - -pub struct Timeline { - token: Option, -} - -struct RaiiToken { - graph: TimeGraph, - timeline: TimelineId, - events: Vec<(String, Instant)>, - // The token must not be Send: - _marker: PhantomData<*const ()> -} - - -impl Drop for RaiiToken { - fn drop(&mut self) { - self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new())); - } -} - -impl TimeGraph { - pub fn new() -> TimeGraph { - TimeGraph { - data: Arc::new(Mutex::new(FxHashMap::default())) - } - } - - pub fn start(&self, - timeline: TimelineId, - work_package_kind: WorkPackageKind, - name: &str) -> Timeline { - { - let mut table = self.data.lock().unwrap(); - - let data = table.entry(timeline).or_insert(PerThread { - timings: Vec::new(), - open_work_package: None, - }); - - assert!(data.open_work_package.is_none()); - data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string())); - } - - Timeline { - token: Some(RaiiToken { - graph: self.clone(), - timeline, - events: Vec::new(), - _marker: PhantomData, - }), - } - } - - fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) { - let end = Instant::now(); - - let mut table = self.data.lock().unwrap(); - let data = table.get_mut(&timeline).unwrap(); - - if let Some((start, work_package_kind, name)) = data.open_work_package.take() { - data.timings.push(Timing { - start, - end, - work_package_kind, - name, - events, - }); - } else { - bug!("end timing without start?") - } - } - - pub fn dump(&self, output_filename: &str) { - let table = self.data.lock().unwrap(); - - for data in table.values() { - assert!(data.open_work_package.is_none()); - } - - let mut threads: Vec = - table.values().map(|data| data.clone()).collect(); - - threads.sort_by_key(|timeline| timeline.timings[0].start); - - let earliest_instant = threads[0].timings[0].start; - let latest_instant = threads.iter() - .map(|timeline| timeline.timings - .last() - .unwrap() - .end) - .max() - .unwrap(); - let max_distance = distance(earliest_instant, latest_instant); - - let mut file = File::create(format!("{}.html", output_filename)).unwrap(); - - writeln!(file, " - - - - - -
- ", - total_height = threads.len() * TIME_LINE_HEIGHT_STRIDE_IN_PX, - width = OUTPUT_WIDTH_IN_PX, - ).unwrap(); - - let mut color = 0; - for (line_index, thread) in threads.iter().enumerate() { - let line_top = line_index * TIME_LINE_HEIGHT_STRIDE_IN_PX; - - for span in &thread.timings { - let start = distance(earliest_instant, span.start); - let end = distance(earliest_instant, span.end); - - let start = normalize(start, max_distance, OUTPUT_WIDTH_IN_PX); - let end = normalize(end, max_distance, OUTPUT_WIDTH_IN_PX); - - let colors = span.work_package_kind.0; - - writeln!(file, "{}", - color, - line_top, - start, - end - start, - TIME_LINE_HEIGHT_IN_PX, - colors[color % colors.len()], - span.name, - ).unwrap(); - - color += 1; - } - } - - writeln!(file, " -
- ").unwrap(); - - let mut idx = 0; - for thread in threads.iter() { - for timing in &thread.timings { - let colors = timing.work_package_kind.0; - let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len(); - writeln!(file, "
", - idx, - colors[idx % colors.len()], - height).unwrap(); - idx += 1; - let max = distance(timing.start, timing.end); - for (i, &(ref event, time)) in timing.events.iter().enumerate() { - let i = i as u64; - let time = distance(timing.start, time); - let at = normalize(time, max, OUTPUT_WIDTH_IN_PX); - writeln!(file, "{}", - at, - TIME_LINE_HEIGHT_IN_PX * i, - event).unwrap(); - } - writeln!(file, "
").unwrap(); - } - } - - writeln!(file, " - - - ").unwrap(); - } -} - -impl Timeline { - pub fn noop() -> Timeline { - Timeline { token: None } - } - - /// Record an event which happened at this moment on this timeline. - /// - /// Events are displayed in the eventual HTML output where you can click on - /// a particular timeline and it'll expand to all of the events that - /// happened on that timeline. This can then be used to drill into a - /// particular timeline and see what events are happening and taking the - /// most time. - pub fn record(&mut self, name: &str) { - if let Some(ref mut token) = self.token { - token.events.push((name.to_string(), Instant::now())); - } - } -} - -fn distance(zero: Instant, x: Instant) -> u64 { - - let duration = x.duration_since(zero); - (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div -} - -fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 { - (max_pixels * distance) / max -} - diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 944569c8b744b..84c652ff238af 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -3,7 +3,6 @@ use crate::back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitc to_llvm_opt_settings}; use crate::llvm::archive_ro::ArchiveRO; use crate::llvm::{self, True, False}; -use crate::time_graph::Timeline; use crate::{ModuleLlvm, LlvmCodegenBackend}; use rustc_codegen_ssa::back::symbol_export; use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, FatLTOInput}; @@ -16,6 +15,7 @@ use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{self, Lto}; use rustc::util::common::time_ext; +use rustc::util::profiling::ProfileCategory; use rustc_data_structures::fx::FxHashMap; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; @@ -37,7 +37,6 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool { } fn prepare_lto(cgcx: &CodegenContext, - timeline: &mut Timeline, diag_handler: &Handler) -> Result<(Vec, Vec<(SerializedModule, CString)>), FatalError> { @@ -68,7 +67,8 @@ fn prepare_lto(cgcx: &CodegenContext, .iter() .filter_map(symbol_filter) .collect::>(); - timeline.record("whitelist"); + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "generate_symbol_white_list_for_thinlto"); info!("{} symbols to preserve in this crate", symbol_white_list.len()); // If we're performing LTO for the entire crate graph, then for each of our @@ -97,6 +97,8 @@ fn prepare_lto(cgcx: &CodegenContext, } for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + format!("load: {}", path.display())); let exported_symbols = cgcx.exported_symbols .as_ref().expect("needs exported symbols for LTO"); symbol_white_list.extend( @@ -121,7 +123,6 @@ fn prepare_lto(cgcx: &CodegenContext, let bc = SerializedModule::FromRlib(bc); upstream_modules.push((bc, CString::new(id).unwrap())); } - timeline.record(&format!("load: {}", path.display())); } } @@ -132,12 +133,11 @@ fn prepare_lto(cgcx: &CodegenContext, /// for further optimization. pub(crate) fn run_fat(cgcx: &CodegenContext, modules: Vec>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline) + cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); - let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?; + let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; let symbol_white_list = symbol_white_list.iter() .map(|c| c.as_ptr()) .collect::>(); @@ -148,7 +148,6 @@ pub(crate) fn run_fat(cgcx: &CodegenContext, cached_modules, upstream_modules, &symbol_white_list, - timeline, ) } @@ -157,12 +156,11 @@ pub(crate) fn run_fat(cgcx: &CodegenContext, /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin(cgcx: &CodegenContext, modules: Vec<(String, ThinBuffer)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline) + cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result<(Vec>, Vec), FatalError> { let diag_handler = cgcx.create_diag_handler(); - let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, timeline, &diag_handler)?; + let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; let symbol_white_list = symbol_white_list.iter() .map(|c| c.as_ptr()) .collect::>(); @@ -175,8 +173,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext, modules, upstream_modules, cached_modules, - &symbol_white_list, - timeline) + &symbol_white_list) } pub(crate) fn prepare_thin( @@ -192,8 +189,7 @@ fn fat_lto(cgcx: &CodegenContext, mut modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule, CString)>, - symbol_white_list: &[*const libc::c_char], - timeline: &mut Timeline) + symbol_white_list: &[*const libc::c_char]) -> Result, FatalError> { info!("going for a fat lto"); @@ -303,7 +299,6 @@ fn fat_lto(cgcx: &CodegenContext, write::llvm_err(&diag_handler, &msg) }) })?; - timeline.record(&format!("link {:?}", name)); serialized_bitcode.push(bc_decoded); } drop(linker); @@ -325,7 +320,6 @@ fn fat_lto(cgcx: &CodegenContext, } save_temp_bitcode(&cgcx, &module, "lto.after-nounwind"); } - timeline.record("passes"); } Ok(LtoModuleCodegen::Fat { @@ -395,8 +389,7 @@ fn thin_lto(cgcx: &CodegenContext, modules: Vec<(String, ThinBuffer)>, serialized_modules: Vec<(SerializedModule, CString)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - symbol_white_list: &[*const libc::c_char], - timeline: &mut Timeline) + symbol_white_list: &[*const libc::c_char]) -> Result<(Vec>, Vec), FatalError> { unsafe { @@ -422,7 +415,6 @@ fn thin_lto(cgcx: &CodegenContext, }); thin_buffers.push(buffer); module_names.push(cname); - timeline.record(&name); } // FIXME: All upstream crates are deserialized internally in the @@ -475,7 +467,6 @@ fn thin_lto(cgcx: &CodegenContext, })?; info!("thin LTO data created"); - timeline.record("data"); let import_map = if cgcx.incr_comp_session_dir.is_some() { ThinLTOImports::from_thin_lto_data(data) @@ -486,7 +477,6 @@ fn thin_lto(cgcx: &CodegenContext, ThinLTOImports::default() }; info!("thin LTO import map loaded"); - timeline.record("import-map-loaded"); let data = ThinData(data); @@ -691,7 +681,6 @@ impl Drop for ThinBuffer { pub unsafe fn optimize_thin_module( thin_module: &mut ThinModule, cgcx: &CodegenContext, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); let tm = (cgcx.tm_factory.0)().map_err(|e| { @@ -738,9 +727,10 @@ pub unsafe fn optimize_thin_module( // Like with "fat" LTO, get some better optimizations if landing pads // are disabled by removing all landing pads. if cgcx.no_landing_pads { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "LLVM_remove_landing_pads"); llvm::LLVMRustMarkAllFunctionsNounwind(llmod); save_temp_bitcode(&cgcx, &module, "thin-lto-after-nounwind"); - timeline.record("nounwind"); } // Up next comes the per-module local analyses that we do for Thin LTO. @@ -756,25 +746,21 @@ pub unsafe fn optimize_thin_module( return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); - timeline.record("rename"); if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); - timeline.record("resolve"); if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); - timeline.record("internalize"); if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; return Err(write::llvm_err(&diag_handler, msg)) } save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); - timeline.record("import"); // Ok now this is a bit unfortunate. This is also something you won't // find upstream in LLVM's ThinLTO passes! This is a hack for now to @@ -807,7 +793,6 @@ pub unsafe fn optimize_thin_module( // fixed in LLVM. llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); - timeline.record("patch"); // Alright now that we've done everything related to the ThinLTO // analysis it's time to run some optimizations! Here we use the same @@ -818,7 +803,6 @@ pub unsafe fn optimize_thin_module( let config = cgcx.config(module.kind); run_pass_manager(cgcx, &module, config, true); save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); - timeline.record("thin-done"); } Ok(module) } diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index db5430a4219a0..dc4dd4e39e17b 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -3,7 +3,6 @@ use crate::back::bytecode::{self, RLIB_BYTECODE_EXTENSION}; use crate::back::lto::ThinBuffer; use crate::base; use crate::consts; -use crate::time_graph::Timeline; use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic}; use crate::llvm_util; use crate::ModuleLlvm; @@ -19,6 +18,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc_codegen_ssa::{ModuleCodegen, CompiledModule}; use rustc::util::common::time_ext; +use rustc::util::profiling::ProfileCategory; use rustc_fs_util::{path_to_c_string, link_or_copy}; use rustc_data_structures::small_c_str::SmallCStr; use errors::{Handler, FatalError}; @@ -305,8 +305,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void pub(crate) unsafe fn optimize(cgcx: &CodegenContext, diag_handler: &Handler, module: &ModuleCodegen, - config: &ModuleConfig, - timeline: &mut Timeline) + config: &ModuleConfig) -> Result<(), FatalError> { let llmod = module.module_llvm.llmod(); @@ -415,19 +414,24 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, diag_handler.abort_if_errors(); // Finally, run the actual optimization passes - time_ext(config.time_passes, - None, - &format!("llvm function passes [{}]", module_name.unwrap()), - || { - llvm::LLVMRustRunFunctionPassManager(fpm, llmod) - }); - timeline.record("fpm"); - time_ext(config.time_passes, - None, - &format!("llvm module passes [{}]", module_name.unwrap()), - || { - llvm::LLVMRunPassManager(mpm, llmod) - }); + { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_function_passes"); + time_ext(config.time_passes, + None, + &format!("llvm function passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRustRunFunctionPassManager(fpm, llmod) + }); + } + { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_module_passes"); + time_ext(config.time_passes, + None, + &format!("llvm module passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRunPassManager(mpm, llmod) + }); + } // Deallocate managers that we're now done with llvm::LLVMDisposePassManager(fpm); @@ -439,11 +443,10 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext, pub(crate) unsafe fn codegen(cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, - config: &ModuleConfig, - timeline: &mut Timeline) + config: &ModuleConfig) -> Result { - timeline.record("codegen"); + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "codegen"); { let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; @@ -494,29 +497,30 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, if write_bc || config.emit_bc_compressed || config.embed_bitcode { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_make_bitcode"); let thin = ThinBuffer::new(llmod); let data = thin.data(); - timeline.record("make-bc"); if write_bc { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode"); if let Err(e) = fs::write(&bc_out, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } - timeline.record("write-bc"); } if config.embed_bitcode { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_embed_bitcode"); embed_bitcode(cgcx, llcx, llmod, Some(data)); - timeline.record("embed-bc"); } if config.emit_bc_compressed { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, + "LLVM_compress_bitcode"); let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); let data = bytecode::encode(&module.name, data); if let Err(e) = fs::write(&dst, data) { diag_handler.err(&format!("failed to write bytecode: {}", e)); } - timeline.record("compress-bc"); } } else if config.embed_bitcode_marker { embed_bitcode(cgcx, llcx, llmod, None); @@ -525,6 +529,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), || -> Result<(), FatalError> { if config.emit_ir { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir"); let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); let out = path_to_c_string(&out); @@ -563,10 +568,10 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback); llvm::LLVMDisposePassManager(cpm); }); - timeline.record("ir"); } if config.emit_asm || asm_to_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_asm"); let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); // We can't use the same module for asm and binary output, because that triggers @@ -581,19 +586,18 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) })?; - timeline.record("asm"); } if write_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_obj"); with_codegen(tm, llmod, config.no_builtins, |cpm| { write_output_file(diag_handler, tm, cpm, llmod, &obj_out, llvm::FileType::ObjectFile) })?; - timeline.record("obj"); } else if asm_to_obj { + let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_asm_to_obj"); let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); run_assembler(cgcx, diag_handler, &assembly, &obj_out); - timeline.record("asm_to_obj"); if !config.emit_asm && !cgcx.save_temps { drop(fs::remove_file(&assembly)); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7b2b9ec24ea0f..0a295c202e655 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -53,7 +53,6 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModul use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; -use rustc::util::time_graph::Timeline; use syntax_pos::symbol::InternedString; use rustc::mir::mono::Stats; pub use llvm_util::target_features; @@ -66,7 +65,6 @@ use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; -use rustc::util::time_graph; use rustc::util::profiling::ProfileCategory; use rustc::util::common::ErrorReported; use rustc_mir::monomorphize; @@ -167,42 +165,37 @@ impl WriteBackendMethods for LlvmCodegenBackend { cgcx: &CodegenContext, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline ) -> Result, FatalError> { - back::lto::run_fat(cgcx, modules, cached_modules, timeline) + back::lto::run_fat(cgcx, modules, cached_modules) } fn run_thin_lto( cgcx: &CodegenContext, modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline ) -> Result<(Vec>, Vec), FatalError> { - back::lto::run_thin(cgcx, modules, cached_modules, timeline) + back::lto::run_thin(cgcx, modules, cached_modules) } unsafe fn optimize( cgcx: &CodegenContext, diag_handler: &Handler, module: &ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline ) -> Result<(), FatalError> { - back::write::optimize(cgcx, diag_handler, module, config, timeline) + back::write::optimize(cgcx, diag_handler, module, config) } unsafe fn optimize_thin( cgcx: &CodegenContext, thin: &mut ThinModule, - timeline: &mut Timeline ) -> Result, FatalError> { - back::lto::optimize_thin_module(thin, cgcx, timeline) + back::lto::optimize_thin_module(thin, cgcx) } unsafe fn codegen( cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline ) -> Result { - back::write::codegen(cgcx, diag_handler, module, config, timeline) + back::write::codegen(cgcx, diag_handler, module, config) } fn prepare_thin( module: ModuleCodegen @@ -336,12 +329,12 @@ impl CodegenBackend for LlvmCodegenBackend { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - sess.profiler(|p| p.start_activity(ProfileCategory::Linking)); + sess.profiler(|p| p.start_activity(ProfileCategory::Linking, "link_crate")); time(sess, "linking", || { back::link::link_binary(sess, &codegen_results, outputs, &codegen_results.crate_name.as_str()); }); - sess.profiler(|p| p.end_activity(ProfileCategory::Linking)); + sess.profiler(|p| p.end_activity(ProfileCategory::Linking, "link_crate")); // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) diff --git a/src/librustc_codegen_ssa/back/lto.rs b/src/librustc_codegen_ssa/back/lto.rs index 7f0eba7b0850b..47e5d9af33ba4 100644 --- a/src/librustc_codegen_ssa/back/lto.rs +++ b/src/librustc_codegen_ssa/back/lto.rs @@ -2,7 +2,6 @@ use super::write::CodegenContext; use crate::traits::*; use crate::ModuleCodegen; -use rustc::util::time_graph::Timeline; use rustc_errors::FatalError; use std::sync::Arc; @@ -67,7 +66,6 @@ impl LtoModuleCodegen { pub unsafe fn optimize( &mut self, cgcx: &CodegenContext, - timeline: &mut Timeline ) -> Result, FatalError> { match *self { LtoModuleCodegen::Fat { ref mut module, .. } => { @@ -75,11 +73,10 @@ impl LtoModuleCodegen { { let config = cgcx.config(module.kind); B::run_lto_pass_manager(cgcx, &module, config, false); - timeline.record("fat-done"); } Ok(module) } - LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin, timeline), + LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin), } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index c84b38cde8185..859dfb99d92b8 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -15,11 +15,10 @@ use rustc::middle::cstore::EncodedMetadata; use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Sanitizer, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use rustc::util::time_graph::{self, TimeGraph, Timeline}; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; -use rustc::util::profiling::SelfProfiler; +use rustc::util::profiling::{ProfileCategory, SelfProfiler}; use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; @@ -33,6 +32,7 @@ use jobserver::{Client, Acquired}; use parking_lot::Mutex as PlMutex; use std::any::Any; +use std::borrow::Cow; use std::fs; use std::io; use std::mem; @@ -197,6 +197,40 @@ impl Clone for TargetMachineFactory { } } +pub struct ProfileGenericActivityTimer { + profiler: Option>>, + category: ProfileCategory, + label: Cow<'static, str>, +} + +impl ProfileGenericActivityTimer { + pub fn start( + profiler: Option>>, + category: ProfileCategory, + label: Cow<'static, str>, + ) -> ProfileGenericActivityTimer { + if let Some(profiler) = &profiler { + let mut p = profiler.lock(); + p.start_activity(category, label.clone()); + } + + ProfileGenericActivityTimer { + profiler, + category, + label, + } + } +} + +impl Drop for ProfileGenericActivityTimer { + fn drop(&mut self) { + if let Some(profiler) = &self.profiler { + let mut p = profiler.lock(); + p.end_activity(self.category, self.label.clone()); + } + } +} + /// Additional resources used by optimize_and_codegen (not module specific) #[derive(Clone)] pub struct CodegenContext { @@ -238,9 +272,6 @@ pub struct CodegenContext { pub cgu_reuse_tracker: CguReuseTracker, // Channel back to the main control thread to send messages to pub coordinator_send: Sender>, - // A reference to the TimeGraph so we can register timings. None means that - // measuring is disabled. - pub time_graph: Option, // The assembler command if no_integrated_as option is enabled, None otherwise pub assembler_cmd: Option> } @@ -277,6 +308,14 @@ impl CodegenContext { self.profiler_active(f) } } + + pub fn profile_activity( + &self, + category: ProfileCategory, + label: impl Into>, + ) -> ProfileGenericActivityTimer { + ProfileGenericActivityTimer::start(self.profiler.clone(), category, label.into()) + } } fn generate_lto_work( @@ -285,11 +324,7 @@ fn generate_lto_work( needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule, WorkProduct)> ) -> Vec<(WorkItem, u64)> { - let mut timeline = cgcx.time_graph.as_ref().map(|tg| { - tg.start(CODEGEN_WORKER_TIMELINE, - CODEGEN_WORK_PACKAGE_KIND, - "generate lto") - }).unwrap_or(Timeline::noop()); + cgcx.profile(|p| p.start_activity(ProfileCategory::Linking, "codegen_run_lto")); let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); @@ -297,17 +332,16 @@ fn generate_lto_work( cgcx, needs_fat_lto, import_only_modules, - &mut timeline, ) .unwrap_or_else(|e| e.raise()); (vec![lto_module], vec![]) } else { assert!(needs_fat_lto.is_empty()); - B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules, &mut timeline) + B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules) .unwrap_or_else(|e| e.raise()) }; - lto_modules.into_iter().map(|module| { + let result = lto_modules.into_iter().map(|module| { let cost = module.cost(); (WorkItem::LTO(module), cost) }).chain(copy_jobs.into_iter().map(|wp| { @@ -315,7 +349,11 @@ fn generate_lto_work( name: wp.cgu_name.clone(), source: wp, }), 0) - })).collect() + })).collect(); + + cgcx.profile(|p| p.end_activity(ProfileCategory::Linking, "codegen_run_lto")); + + result } pub struct CompiledModules { @@ -345,7 +383,6 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { pub fn start_async_codegen( backend: B, tcx: TyCtxt<'_, '_, '_>, - time_graph: Option, metadata: EncodedMetadata, coordinator_receive: Receiver>, total_cgus: usize @@ -469,7 +506,6 @@ pub fn start_async_codegen( coordinator_receive, total_cgus, sess.jobserver.clone(), - time_graph.clone(), Arc::new(modules_config), Arc::new(metadata_config), Arc::new(allocator_config)); @@ -483,7 +519,6 @@ pub fn start_async_codegen( linker_info, crate_info, - time_graph, coordinator_send: tcx.tx_to_llvm_workers.lock().clone(), codegen_worker_receive, shared_emitter_main, @@ -728,19 +763,18 @@ pub enum FatLTOInput { fn execute_work_item( cgcx: &CodegenContext, work_item: WorkItem, - timeline: &mut Timeline ) -> Result, FatalError> { let module_config = cgcx.config(work_item.module_kind()); match work_item { WorkItem::Optimize(module) => { - execute_optimize_work_item(cgcx, module, module_config, timeline) + execute_optimize_work_item(cgcx, module, module_config) } WorkItem::CopyPostLtoArtifacts(module) => { - execute_copy_from_cache_work_item(cgcx, module, module_config, timeline) + execute_copy_from_cache_work_item(cgcx, module, module_config) } WorkItem::LTO(module) => { - execute_lto_work_item(cgcx, module, module_config, timeline) + execute_lto_work_item(cgcx, module, module_config) } } } @@ -756,12 +790,11 @@ fn execute_optimize_work_item( cgcx: &CodegenContext, module: ModuleCodegen, module_config: &ModuleConfig, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); unsafe { - B::optimize(cgcx, &diag_handler, &module, module_config, timeline)?; + B::optimize(cgcx, &diag_handler, &module, module_config)?; } // After we've done the initial round of optimizations we need to @@ -818,7 +851,7 @@ fn execute_optimize_work_item( Ok(match lto_type { ComputedLtoType::No => { let module = unsafe { - B::codegen(cgcx, &diag_handler, module, module_config, timeline)? + B::codegen(cgcx, &diag_handler, module, module_config)? }; WorkItemResult::Compiled(module) } @@ -854,7 +887,6 @@ fn execute_copy_from_cache_work_item( cgcx: &CodegenContext, module: CachedModuleCodegen, module_config: &ModuleConfig, - _: &mut Timeline ) -> Result, FatalError> { let incr_comp_session_dir = cgcx.incr_comp_session_dir .as_ref() @@ -916,13 +948,12 @@ fn execute_lto_work_item( cgcx: &CodegenContext, mut module: lto::LtoModuleCodegen, module_config: &ModuleConfig, - timeline: &mut Timeline ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); unsafe { - let module = module.optimize(cgcx, timeline)?; - let module = B::codegen(cgcx, &diag_handler, module, module_config, timeline)?; + let module = module.optimize(cgcx)?; + let module = B::codegen(cgcx, &diag_handler, module, module_config)?; Ok(WorkItemResult::Compiled(module)) } } @@ -977,7 +1008,6 @@ fn start_executing_work( coordinator_receive: Receiver>, total_cgus: usize, jobserver: Client, - time_graph: Option, modules_config: Arc, metadata_config: Arc, allocator_config: Arc @@ -1065,7 +1095,6 @@ fn start_executing_work( cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(), coordinator_send, diag_emitter: shared_emitter.clone(), - time_graph, output_filenames: tcx.output_filenames(LOCAL_CRATE), regular_module_config: modules_config, metadata_module_config: metadata_config, @@ -1570,12 +1599,6 @@ fn start_executing_work( } pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; -pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId = - time_graph::TimelineId(CODEGEN_WORKER_ID); -pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]); -const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]); fn spawn_work( cgcx: CodegenContext, @@ -1625,13 +1648,12 @@ fn spawn_work( // as a diagnostic was already sent off to the main thread - just // surface that there was an error in this worker. bomb.result = { - let timeline = cgcx.time_graph.as_ref().map(|tg| { - tg.start(time_graph::TimelineId(cgcx.worker), - LLVM_WORK_PACKAGE_KIND, - &work.name()) - }); - let mut timeline = timeline.unwrap_or(Timeline::noop()); - execute_work_item(&cgcx, work, &mut timeline).ok() + let label = work.name(); + cgcx.profile(|p| p.start_activity(ProfileCategory::Codegen, label.clone())); + let result = execute_work_item(&cgcx, work).ok(); + cgcx.profile(|p| p.end_activity(ProfileCategory::Codegen, label)); + + result }; }); } @@ -1785,7 +1807,6 @@ pub struct OngoingCodegen { pub windows_subsystem: Option, pub linker_info: LinkerInfo, pub crate_info: CrateInfo, - pub time_graph: Option, pub coordinator_send: Sender>, pub codegen_worker_receive: Receiver>, pub shared_emitter_main: SharedEmitterMain, @@ -1814,10 +1835,6 @@ impl OngoingCodegen { sess.abort_if_errors(); - if let Some(time_graph) = self.time_graph { - time_graph.dump(&format!("{}-timings", self.crate_name)); - } - let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 39ce15e477296..48743be3a2551 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -29,7 +29,6 @@ use rustc::util::profiling::ProfileCategory; use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; use rustc_mir::monomorphize::item::DefPathBasedNames; -use rustc::util::time_graph; use rustc_mir::monomorphize::Instance; use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; use rustc::util::nodemap::FxHashMap; @@ -528,11 +527,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; -pub const CODEGEN_WORKER_TIMELINE: time_graph::TimelineId = - time_graph::TimelineId(CODEGEN_WORKER_ID); -pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = - time_graph::WorkPackageKind(&["#DE9597", "#FED1D3", "#FDC5C7", "#B46668", "#88494B"]); - pub fn codegen_crate( backend: B, @@ -545,7 +539,7 @@ pub fn codegen_crate( let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); // Codegen the metadata. - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate metadata")); let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], @@ -555,7 +549,7 @@ pub fn codegen_crate( let metadata = time(tcx.sess, "write metadata", || { backend.write_metadata(tcx, &mut metadata_llvm_module) }); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate metadata")); let metadata_module = ModuleCodegen { name: metadata_cgu_name, @@ -563,19 +557,12 @@ pub fn codegen_crate( kind: ModuleKind::Metadata, }; - let time_graph = if tcx.sess.opts.debugging_opts.codegen_time_graph { - Some(time_graph::TimeGraph::new()) - } else { - None - }; - // Skip crate items and just output metadata in -Z no-codegen mode. if tcx.sess.opts.debugging_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { let ongoing_codegen = start_async_codegen( backend, tcx, - time_graph, metadata, rx, 1); @@ -609,7 +596,6 @@ pub fn codegen_crate( let ongoing_codegen = start_async_codegen( backend.clone(), tcx, - time_graph.clone(), metadata, rx, codegen_units.len()); @@ -676,15 +662,14 @@ pub fn codegen_crate( match cgu_reuse { CguReuse::No => { - let _timing_guard = time_graph.as_ref().map(|time_graph| { - time_graph.start(CODEGEN_WORKER_TIMELINE, - CODEGEN_WORK_PACKAGE_KIND, - &format!("codegen {}", cgu.name())) - }); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, + format!("codegen {}", cgu.name()))); let start_time = Instant::now(); let stats = backend.compile_codegen_unit(tcx, *cgu.name()); all_stats.extend(stats); total_codegen_time += start_time.elapsed(); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, + format!("codegen {}", cgu.name()))); false } CguReuse::PreLto => { diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs index d8fb7c608c8af..23bb7179557b9 100644 --- a/src/librustc_codegen_ssa/traits/write.rs +++ b/src/librustc_codegen_ssa/traits/write.rs @@ -3,7 +3,6 @@ use crate::back::write::{CodegenContext, ModuleConfig, FatLTOInput}; use crate::{CompiledModule, ModuleCodegen}; use rustc::dep_graph::WorkProduct; -use rustc::util::time_graph::Timeline; use rustc_errors::{FatalError, Handler}; pub trait WriteBackendMethods: 'static + Sized + Clone { @@ -20,7 +19,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { cgcx: &CodegenContext, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline, ) -> Result, FatalError>; /// Performs thin LTO by performing necessary global analysis and returning two /// lists, one of the modules that need optimization and another for modules that @@ -29,7 +27,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { cgcx: &CodegenContext, modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, - timeline: &mut Timeline, ) -> Result<(Vec>, Vec), FatalError>; fn print_pass_timings(&self); unsafe fn optimize( @@ -37,19 +34,16 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { diag_handler: &Handler, module: &ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline, ) -> Result<(), FatalError>; unsafe fn optimize_thin( cgcx: &CodegenContext, thin: &mut ThinModule, - timeline: &mut Timeline, ) -> Result, FatalError>; unsafe fn codegen( cgcx: &CodegenContext, diag_handler: &Handler, module: ModuleCodegen, config: &ModuleConfig, - timeline: &mut Timeline, ) -> Result; fn prepare_thin( module: ModuleCodegen diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d61ccd5605b60..5bb47bda17b33 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -67,7 +67,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { .set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error); hygiene::set_default_edition(sess.edition()); - sess.profiler(|p| p.start_activity(ProfileCategory::Parsing)); + sess.profiler(|p| p.start_activity(ProfileCategory::Parsing, "parsing")); let krate = time(sess, "parsing", || match *input { Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess), Input::Str { @@ -75,7 +75,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { ref name, } => parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess), })?; - sess.profiler(|p| p.end_activity(ProfileCategory::Parsing)); + sess.profiler(|p| p.end_activity(ProfileCategory::Parsing, "parsing")); sess.diagnostic().set_continue_after_error(true); @@ -374,7 +374,7 @@ fn configure_and_expand_inner<'a>( syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts); // Expand all macros - sess.profiler(|p| p.start_activity(ProfileCategory::Expansion)); + sess.profiler(|p| p.start_activity(ProfileCategory::Expansion, "macro expansion")); krate = time(sess, "expansion", || { // Windows dlls do not have rpaths, so they don't know how to find their // dependencies. It's up to us to tell the system where to find all the @@ -449,7 +449,7 @@ fn configure_and_expand_inner<'a>( } krate }); - sess.profiler(|p| p.end_activity(ProfileCategory::Expansion)); + sess.profiler(|p| p.end_activity(ProfileCategory::Expansion, "macro expansion")); time(sess, "maybe building test harness", || { syntax::test::modify_for_testing( @@ -1018,9 +1018,9 @@ pub fn start_codegen<'tcx>( ::rustc::middle::dependency_format::calculate(tcx) }); - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::Codegen, "codegen crate")); let codegen = time(tcx.sess, "codegen", move || codegen_backend.codegen_crate(tcx, rx)); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen, "codegen crate")); if log_enabled!(::log::Level::Info) { println!("Post-codegen"); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ebb617c23c6ca..cbed7d26a9950 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -317,7 +317,7 @@ pub fn provide(providers: &mut Providers<'_>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { - tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking)); + tcx.sess.profiler(|p| p.start_activity(ProfileCategory::TypeChecking, "type-check crate")); // this ensures that later parts of type checking can assume that items // have valid types and not error @@ -368,7 +368,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) check_unused::check_crate(tcx); check_for_entry_fn(tcx); - tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking)); + tcx.sess.profiler(|p| p.end_activity(ProfileCategory::TypeChecking, "type-check crate")); if tcx.sess.err_count() == 0 { Ok(()) From 4888b1fb99f1bf6a58bebaededdfbf4477383634 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:45:45 +0100 Subject: [PATCH 030/157] we can now skip should_panic tests with the libtest harness --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/btree/map.rs | 5 ----- src/liballoc/tests/slice.rs | 18 ------------------ src/liballoc/tests/str.rs | 11 ----------- src/liballoc/tests/string.rs | 9 --------- src/liballoc/tests/vec.rs | 12 ------------ src/liballoc/tests/vec_deque.rs | 1 - src/libcore/tests/cell.rs | 3 --- src/libcore/tests/iter.rs | 2 -- src/libcore/tests/num/bignum.rs | 14 -------------- src/libcore/tests/option.rs | 3 --- src/libcore/tests/result.rs | 3 --- src/libcore/tests/slice.rs | 7 ------- src/libcore/tests/time.rs | 2 -- 14 files changed, 1 insertion(+), 91 deletions(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac42..a97a790f5a2d8 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index f14750089c956..844afe870766b 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_equal_excluded() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(2), Excluded(2))); @@ -234,7 +233,6 @@ fn test_range_equal_excluded() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_1() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Included(2))); @@ -242,7 +240,6 @@ fn test_range_backwards_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_2() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Excluded(2))); @@ -250,7 +247,6 @@ fn test_range_backwards_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_3() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Included(2))); @@ -258,7 +254,6 @@ fn test_range_backwards_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_4() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Excluded(2))); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index feba46b0fad78..fb99c95fc6842 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -258,7 +258,6 @@ fn test_swap_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -632,7 +631,6 @@ fn test_insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -657,7 +655,6 @@ fn test_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -939,7 +936,6 @@ fn test_windowsator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_windowsator_0() { let v = &[1, 2, 3, 4]; let _it = v.windows(0); @@ -964,7 +960,6 @@ fn test_chunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks(0); @@ -989,7 +984,6 @@ fn test_chunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks_exact(0); @@ -1014,7 +1008,6 @@ fn test_rchunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks(0); @@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks_exact(0); @@ -1092,7 +1084,6 @@ fn test_vec_default() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(!0); @@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(!0); @@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); @@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_exact_mut(0); @@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_mut(0); @@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_exact_mut(0); @@ -1411,7 +1397,6 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] -#[cfg(not(miri))] // Miri does not support panics fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1461,6 @@ fn test_copy_from_slice() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_longer() { let src = [0, 1, 2, 3]; let mut dst = [0; 5]; @@ -1485,7 +1469,6 @@ fn test_copy_from_slice_dst_longer() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_shorter() { let src = [0, 1, 2, 3]; let mut dst = [0; 3]; @@ -1605,7 +1588,6 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads -#[cfg(not(miri))] // Miri does not support panics fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..f2dc19a42296a 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -351,7 +351,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of bounds")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!("abc", 0..5, "abc"); } @@ -361,7 +360,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!("abc", 0..2, "abc"); } @@ -409,7 +407,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v: String = $data.into(); let v: &str = &v; @@ -418,7 +415,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v: String = $data.into(); let v: &mut str = &mut v; @@ -514,7 +510,6 @@ mod slice_index { #[test] #[should_panic] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail() { &"中华Việt Nam"[0..2]; } @@ -666,14 +661,12 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] #[should_panic(expected="luctus, im`[...]")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -894,7 +885,6 @@ fn test_as_bytes() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -984,7 +974,6 @@ fn test_split_at_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e93d84fe3b97..7e75b8c4f28c8 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -231,7 +231,6 @@ fn test_split_off_empty() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_past_end() { let orig = "Hello, world!"; let mut split = String::from(orig); @@ -240,7 +239,6 @@ fn test_split_off_past_end() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_mid_char() { let mut orig = String::from("山"); orig.split_off(1); @@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_truncate_split_codepoint() { let mut s = String::from("\u{FC}"); // ü s.truncate(1); @@ -324,7 +321,6 @@ fn remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn remove_bad() { "ศ".to_string().remove(1); } @@ -360,13 +356,11 @@ fn insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad2() { "ệ".to_string().insert(1, 't'); } @@ -447,7 +441,6 @@ fn test_replace_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); @@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); @@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 6e4ca1d90e642..545332bcd6a2f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -368,7 +368,6 @@ fn test_vec_truncate_drop() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -392,7 +391,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let vec = vec![1, 2, 3]; let _ = vec[3]; @@ -400,7 +398,6 @@ fn test_index_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_1() { let x = vec![1, 2, 3, 4, 5]; &x[!0..]; @@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_2() { let x = vec![1, 2, 3, 4, 5]; &x[..6]; @@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_3() { let x = vec![1, 2, 3, 4, 5]; &x[!0..4]; @@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_4() { let x = vec![1, 2, 3, 4, 5]; &x[1..6]; @@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_5() { let x = vec![1, 2, 3, 4, 5]; &x[3..2]; @@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_empty() { let mut vec = Vec::::new(); vec.swap_remove(0); @@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..6); @@ -585,7 +576,6 @@ fn test_drain_max_vec_size() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..=5); @@ -615,7 +605,6 @@ fn test_splice_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; @@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 16ddc1444fcf9..e0fe10a55f55c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -108,7 +108,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..56f295dff8e43 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn discard_doesnt_unborrow() { let x = RefCell::new(0); let _b = x.borrow(); @@ -350,7 +349,6 @@ fn refcell_ref_coercion() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_swap_borrows() { let x = RefCell::new(0); let _b = x.borrow(); @@ -360,7 +358,6 @@ fn refcell_swap_borrows() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_replace_borrows() { let x = RefCell::new(0); let _b = x.borrow(); diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index d880abb181c20..4652fc329dc02 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); @@ -1414,7 +1413,6 @@ fn test_rposition() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index 956c22c998219..b873f1dd0652f 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big; #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_from_u64_overflow() { Big::from_u64(0x1000000); } @@ -20,14 +19,12 @@ fn test_add() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_1() { Big::from_small(1).add(&Big::from_u64(0xffffff)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_2() { Big::from_u64(0xffffff).add(&Big::from_small(1)); } @@ -45,7 +42,6 @@ fn test_add_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_small_overflow() { Big::from_u64(0xffffff).add_small(1); } @@ -61,14 +57,12 @@ fn test_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_1() { Big::from_u64(0x10665).sub(&Big::from_u64(0x10666)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_2() { Big::from_small(0).sub(&Big::from_u64(0x123456)); } @@ -82,7 +76,6 @@ fn test_mul_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_small_overflow() { Big::from_u64(0x800000).mul_small(2); } @@ -101,14 +94,12 @@ fn test_mul_pow2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_1() { Big::from_u64(0x1).mul_pow2(24); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_2() { Big::from_u64(0x123).mul_pow2(16); } @@ -127,14 +118,12 @@ fn test_mul_pow5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_1() { Big::from_small(1).mul_pow5(12); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_2() { Big::from_small(230).mul_pow5(8); } @@ -152,14 +141,12 @@ fn test_mul_digits() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_1() { Big::from_u64(0x800000).mul_digits(&[2]); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_2() { Big::from_u64(0x1000).mul_digits(&[0, 0x10]); } @@ -219,7 +206,6 @@ fn test_get_bit() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_get_bit_out_of_range() { Big::from_small(42).get_bit(24); } diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 87ce2720c5918..b059b134868d9 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,7 +69,6 @@ fn test_option_dance() { } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -130,7 +129,6 @@ fn test_unwrap() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -138,7 +136,6 @@ fn test_unwrap_panic1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index bbc8568517667..1fab07526a07f 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,7 +117,6 @@ fn test_unwrap_or_else() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -139,7 +138,6 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -153,7 +151,6 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 31d16e0e32057..ac9c17a0f7c35 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,7 +782,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -792,7 +791,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -842,7 +840,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v = $data; let v: &[_] = &v; @@ -851,7 +848,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1304,7 +1300,6 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 09aae4583482f..6efd22572dc18 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -107,14 +107,12 @@ fn checked_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad1() { let _ = Duration::new(0, 0) - Duration::new(0, 1); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad2() { let _ = Duration::new(0, 0) - Duration::new(1, 0); } From 52d9fa827d3cf5ef5fc0e2042ca1fc7f6dc391ed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:52:45 +0100 Subject: [PATCH 031/157] enabled too many tests --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/slice.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index a97a790f5a2d8..0930f8dacd494 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri does not support panics nor entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index fb99c95fc6842..b54c128a0249a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1397,6 +1397,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1588,6 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads +#[cfg(not(miri))] // Miri does not support threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { From 8629fd3e4e5184852352ea1bb18bb1c8465ffac3 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 9 Feb 2019 22:16:58 +0000 Subject: [PATCH 032/157] Improvements to comments in libstd, libcore, liballoc. --- src/libcore/iter/adapters/mod.rs | 4 ++-- src/libcore/mem.rs | 9 ++++++--- src/libcore/num/dec2flt/algorithm.rs | 2 +- src/libcore/num/dec2flt/mod.rs | 6 +++--- src/libcore/num/dec2flt/parse.rs | 2 +- src/libcore/num/flt2dec/decoder.rs | 2 +- src/libcore/num/flt2dec/mod.rs | 14 +++++++------- src/libcore/pin.rs | 2 +- src/libcore/str/mod.rs | 8 ++++---- src/libcore/task/wake.rs | 2 +- src/libstd/collections/hash/map.rs | 2 +- src/libstd/collections/hash/set.rs | 2 +- src/libstd/fs.rs | 2 +- src/libstd/sync/condvar.rs | 12 ++++++------ src/libstd/sys/windows/pipe.rs | 6 +++--- 15 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index d4ad22c16bbfa..cccd51b577930 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1198,7 +1198,7 @@ impl Peekable { } } -/// An iterator that rejects elements while `predicate` is true. +/// An iterator that rejects elements while `predicate` returns `true`. /// /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. @@ -1286,7 +1286,7 @@ impl Iterator for SkipWhile impl FusedIterator for SkipWhile where I: FusedIterator, P: FnMut(&I::Item) -> bool {} -/// An iterator that only accepts elements while `predicate` is true. +/// An iterator that only accepts elements while `predicate` returns `true`. /// /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 90e84d0b28c3b..3d2fcdc979377 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1111,11 +1111,12 @@ impl DerefMut for ManuallyDrop { /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. +// // FIXME before stabilizing, explain how to initialize a struct field-by-field. #[allow(missing_debug_implementations)] #[unstable(feature = "maybe_uninit", issue = "53491")] #[derive(Copy)] -// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`. +// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`. pub union MaybeUninit { uninit: (), value: ManuallyDrop, @@ -1125,13 +1126,13 @@ pub union MaybeUninit { impl Clone for MaybeUninit { #[inline(always)] fn clone(&self) -> Self { - // Not calling T::clone(), we cannot know if we are initialized enough for that. + // Not calling `T::clone()`, we cannot know if we are initialized enough for that. *self } } impl MaybeUninit { - /// Create a new `MaybeUninit` initialized with the given value. + /// Creates a new `MaybeUninit` initialized with the given value. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. @@ -1239,6 +1240,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] @@ -1277,6 +1279,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index 3b57bb7544b35..a83134a6b2ca4 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -326,7 +326,7 @@ pub fn algorithm_m(f: &Big, e: i16) -> T { round_by_remainder(v, rem, q, z) } -/// Skip over most Algorithm M iterations by checking the bit length. +/// Skips over most Algorithm M iterations by checking the bit length. fn quick_start(u: &mut Big, v: &mut Big, k: &mut i16) { // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v). // The estimate is off by at most 1, but always an under-estimate, so the error on log(u) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 47ea5aa5ff000..d62cdae0688be 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) { } } -/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and -/// Algorithm M will compute while working on the given decimal. +/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R +/// and Algorithm M will compute while working on the given decimal. fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { // We don't need to worry too much about overflow here thanks to trivial_cases() and the // parser, which filter out the most extreme inputs for us. @@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { } } -/// Detect obvious overflows and underflows without even looking at the decimal digits. +/// Detects obvious overflows and underflows without even looking at the decimal digits. fn trivial_cases(decimal: &Decimal) -> Option { // There were zeros but they were stripped by simplify() if decimal.integral.is_empty() && decimal.fractional.is_empty() { diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 933f8c1d3f781..f970595452ec9 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult { } } -/// Carve off decimal digits up to the first non-digit character. +/// Carves off decimal digits up to the first non-digit character. fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { let mut i = 0; while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index a3bf783976bbd..a8da31d3e4858 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat; /// /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will /// round to the original value. The range is inclusive only when -/// `inclusive` is true. +/// `inclusive` is `true`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Decoded { /// The scaled mantissa. diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index f9b46a12f7fef..defd4247f4ea4 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, } } -/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form -/// with at least given number of significant digits. When `upper` is true, +/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential +/// form with at least the given number of significant digits. When `upper` is `true`, /// the exponent will be prefixed by `E`; otherwise that's `e`. The result is /// stored to the supplied parts array and a slice of written parts is returned. /// /// `min_digits` can be less than the number of actual significant digits in `buf`; /// it will be ignored and full digits will be printed. It is only used to print -/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that -/// it will only print given digits and nothing else. +/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that +/// it will only print the given digits and nothing else. fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { assert!(!buf.is_empty()); @@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static } } -/// Formats given floating point number into the decimal form with at least +/// Formats the given floating point number into the decimal form with at least /// given number of fractional digits. The result is stored to the supplied parts /// array while utilizing given byte buffer as a scratch. `upper` is currently /// unused but left for the future decision to change the case of non-finite values, @@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Formats given floating point number into the decimal form or +/// Formats the given floating point number into the decimal form or /// the exponential form, depending on the resulting exponent. The result is /// stored to the supplied parts array while utilizing given byte buffer /// as a scratch. `upper` is used to determine the case of non-finite values @@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Returns rather crude approximation (upper bound) for the maximum buffer size +/// Returns a rather crude approximation (upper bound) for the maximum buffer size /// calculated from the given decoded exponent. /// /// The exact limit is: diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index fb78f5e5a2384..cf55b6c379d04 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -1,4 +1,4 @@ -//! Types which pin data to its location in memory +//! Types that pin data to its location in memory. //! //! It is sometimes useful to have objects that are guaranteed to not move, //! in the sense that their placement in memory does not change, and can thus be relied upon. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 53334adadb856..528281d317be3 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2968,7 +2968,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3143,7 +3143,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3326,7 +3326,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3402,7 +3402,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 21f0a8cea4168..12f812d3bed3e 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -108,7 +108,7 @@ impl Waker { unsafe { (self.waker.vtable.wake)(self.waker.data) } } - /// Returns whether or not this `Waker` and other `Waker` have awaken the same task. + /// Returns `true` if this `Waker` and another `Waker` have awoken the same task. /// /// This function works on a best-effort basis, and may return false even /// when the `Waker`s would awaken the same task. However, if this function diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 928de29b297fc..1d45df499d86b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke use super::table::BucketState::{Empty, Full}; use super::table::Fallibility::{Fallible, Infallible}; -const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two +const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two /// The default behavior of HashMap implements a maximum load factor of 90.9%. #[derive(Clone)] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 8a599c11b2095..1e7d1f1ad58fa 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -8,7 +8,7 @@ use super::Recover; use super::map::{self, HashMap, Keys, RandomState}; // Future Optimization (FIXME!) -// ============================= +// ============================ // // Iteration over zero sized values is a noop. There is no need // for `bucket.val` in the case of HashSet. I suppose we would need HKT diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..93cee50af13e5 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,7 +211,7 @@ pub struct DirBuilder { recursive: bool, } -/// How large a buffer to pre-allocate before reading the entire file. +/// Indicates how large a buffer to pre-allocate before reading the entire file. fn initial_buffer_size(file: &File) -> usize { // Allocate one extra byte so the buffer doesn't need to grow before the // final `read` call at the end of the file. Don't worry about `usize` diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 5ebb61754e1ff..4ad383aa5b613 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is false, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 07f4f5f0e58c4..b38727830f37f 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -37,9 +37,9 @@ pub struct Pipes { /// /// The ours/theirs pipes are *not* specifically readable or writable. Each /// one only supports a read or a write, but which is which depends on the -/// boolean flag given. If `ours_readable` is true then `ours` is readable where -/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is -/// writable where `theirs` is readable. +/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and +/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours` +/// is writable and `theirs` is readable. /// /// Also note that the `ours` pipe is always a handle opened up in overlapped /// mode. This means that technically speaking it should only ever be used From e25df326caf38c1a8559fc6fa633ad60ab401e12 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 17:53:22 +0300 Subject: [PATCH 033/157] consistent naming for duration_float methods and additional f32 methods --- src/libcore/time.rs | 130 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 91161ca477e39..c8f23fd90bd7a 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -22,6 +22,7 @@ const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; +const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -510,15 +511,34 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.as_float_secs(), 2.7); + /// assert_eq!(dur.as_secs_f64(), 2.7); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub const fn as_float_secs(&self) -> f64 { + pub const fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) } - /// Creates a new `Duration` from the specified number of seconds. + /// Returns the number of seconds contained by this `Duration` as `f32`. + /// + /// The returned value does include the fractional (nanosecond) part of the duration. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.as_secs_f32(), 2.7); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub const fn as_secs_f32(&self) -> f32 { + (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) + } + + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f64`. /// /// # Panics /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. @@ -528,12 +548,12 @@ impl Duration { /// #![feature(duration_float)] /// use std::time::Duration; /// - /// let dur = Duration::from_float_secs(2.7); + /// let dur = Duration::from_secs_f64(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn from_float_secs(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -551,6 +571,40 @@ impl Duration { } } + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f32`. + /// + /// # Panics + /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::from_secs_f32(2.7); + /// assert_eq!(dur, Duration::new(2, 700_000_000)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn from_secs_f32(secs: f32) -> Duration { + let nanos = secs * (NANOS_PER_SEC as f32); + if !nanos.is_finite() { + panic!("got non-finite value when converting float to duration"); + } + if nanos >= MAX_NANOS_F32 { + panic!("overflow when converting float to duration"); + } + if nanos < 0.0 { + panic!("underflow when converting float to duration"); + } + let nanos = nanos as u128; + Duration { + secs: (nanos / (NANOS_PER_SEC as u128)) as u64, + nanos: (nanos % (NANOS_PER_SEC as u128)) as u32, + } + } + /// Multiplies `Duration` by `f64`. /// /// # Panics @@ -568,7 +622,27 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn mul_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(rhs * self.as_float_secs()) + Duration::from_secs_f64(rhs * self.as_secs_f64()) + } + + /// Multiplies `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn mul_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(rhs * self.as_secs_f32()) } /// Divide `Duration` by `f64`. @@ -589,7 +663,28 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn div_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(self.as_float_secs() / rhs) + Duration::from_secs_f64(self.as_secs_f64() / rhs) + } + + /// Divide `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that truncation is used, not rounding + /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(self.as_secs_f32() / rhs) } /// Divide `Duration` by `Duration` and return `f64`. @@ -605,8 +700,25 @@ impl Duration { /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn div_duration(self, rhs: Duration) -> f64 { - self.as_float_secs() / rhs.as_float_secs() + pub fn div_duration_f64(self, rhs: Duration) -> f64 { + self.as_secs_f64() / rhs.as_secs_f64() + } + + /// Divide `Duration` by `Duration` and return `f32`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur1 = Duration::new(2, 700_000_000); + /// let dur2 = Duration::new(5, 400_000_000); + /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_duration_f32(self, rhs: Duration) -> f32 { + self.as_secs_f32() / rhs.as_secs_f32() } } From 35c19c5b3d1fe8675132ea96e014e37455653ce8 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 18:06:13 +0300 Subject: [PATCH 034/157] move MAX_NANOS_F64/32 to methods --- src/libcore/time.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c8f23fd90bd7a..d3f80835c0175 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -21,8 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000; const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; -const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; -const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -554,6 +552,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f64(secs: f64) -> Duration { + const MAX_NANOS_F64: f64 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -588,6 +588,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f32(secs: f32) -> Duration { + const MAX_NANOS_F32: f32 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; let nanos = secs * (NANOS_PER_SEC as f32); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); From d4b2071b1faeaa15ecbad7dc74a94def96200d87 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 11 Mar 2019 15:54:57 +0000 Subject: [PATCH 035/157] Resolved nits raised in review. --- src/libstd/sync/condvar.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 4ad383aa5b613..c383f21dcd752 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is `false`, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } From 980871af270314d1e4dd42828d9a7c76d6e0c89a Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 19:57:53 +0300 Subject: [PATCH 036/157] fix tests --- src/libcore/time.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index d3f80835c0175..c4d4c4622f3a4 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -638,8 +638,10 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// // note that due to rounding errors result is slightly different + /// // from 8.478 + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -679,7 +681,9 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that due to rounding errors result is slightly + /// // different from 0.859_872_611 + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576)); /// // note that truncation is used, not rounding /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); /// ``` @@ -698,7 +702,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -715,7 +719,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From 197efb05243976a631107f1d6ad88bff65fd43e9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 11 Mar 2019 18:59:41 +0000 Subject: [PATCH 037/157] fix test --- src/libcore/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c4d4c4622f3a4..f106d06d2ffc1 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,9 +639,9 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 + /// // from 8.478 anf 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From 78b248dc4c17581211aaed5c3a449e5b07ebdb52 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 12 Mar 2019 16:42:18 +0300 Subject: [PATCH 038/157] fix typo --- src/libcore/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index f106d06d2ffc1..ae6d8078fd236 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,7 +639,7 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 anf 847800.0 + /// // from 8.478 and 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` From 1ae131211be24a337877e6dbcd9b6c52a86b9511 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 12 Mar 2019 14:43:49 +0100 Subject: [PATCH 039/157] Explain the bits of `UndefMask` --- src/librustc/mir/interpret/allocation.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 004804f7c211e..2ce9a4a0f204d 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -613,6 +613,8 @@ impl DerefMut for Relocations { type Block = u64; +/// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte +/// is defined. If it is `false` the byte is undefined. #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct UndefMask { blocks: Vec, From 2a1eb1cef1a36c6f0a9d2e347529561c1293044e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 12 Mar 2019 15:00:12 +0100 Subject: [PATCH 040/157] Document the precomputation algorithm's purpose --- src/librustc_mir/interpret/memory.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index fba0a9af21392..6ea200d4e4fad 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -791,6 +791,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { let undef_mask = &self.get(src.alloc_id)?.undef_mask; + // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`), + // a naive undef mask copying algorithm would repeatedly have to read the undef mask from + // the source and write it to the destination. Even if we optimized the memory accesses, + // we'd be doing all of this `repeat` times. + // Therefor we precompute a compressed version of the undef mask of the source value and + // then write it back `repeat` times without computing any more information from the source. + // a precomputed cache for ranges of defined/undefined bits // 0000010010001110 will become // [5, 1, 2, 1, 3, 3, 1] From 507448945612f6b6f80a08a943e88d9a3a14b52f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 12 Mar 2019 17:37:22 +0100 Subject: [PATCH 041/157] Unregress using scalar unions in constants. --- src/librustc_mir/const_eval.rs | 26 +++++++++++++------------- src/test/ui/consts/union_constant.rs | 11 +++++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/consts/union_constant.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 365cb508b0925..d97be0b28725c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( fn mplace_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, mplace: MPlaceTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { +) -> ty::Const<'tcx> { let MemPlace { ptr, align, meta } = *mplace; // extract alloc-offset pair assert!(meta.is_none()); - let ptr = ptr.to_ptr()?; - let alloc = ecx.memory.get(ptr.alloc_id)?; + let ptr = ptr.to_ptr().unwrap(); + let alloc = ecx.memory.get(ptr.alloc_id).unwrap(); assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes()); let mut alloc = alloc.clone(); @@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>( // interned this? I thought that is the entire point of that `FinishStatic` stuff? let alloc = ecx.tcx.intern_const_alloc(alloc); let val = ConstValue::ByRef(ptr, alloc); - Ok(ty::Const { val, ty: mplace.layout.ty }) + ty::Const { val, ty: mplace.layout.ty } } fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { - // We do not normalize just any data. Only scalar layout and slices. +) -> ty::Const<'tcx> { + // We do not normalize just any data. Only non-union scalars and slices. let normalize = match op.layout.abi { - layout::Abi::Scalar(..) => true, + layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()), layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(), _ => false, }; @@ -100,11 +100,11 @@ fn op_to_const<'tcx>( let val = match normalized_op { Ok(mplace) => return mplace_to_const(ecx, mplace), Err(Immediate::Scalar(x)) => - ConstValue::Scalar(x.not_undef()?), + ConstValue::Scalar(x.not_undef().unwrap()), Err(Immediate::ScalarPair(a, b)) => - ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?), + ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()), }; - Ok(ty::Const { val, ty: op.layout.ty }) + ty::Const { val, ty: op.layout.ty } } fn eval_body_and_ecx<'a, 'mir, 'tcx>( @@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>( let field = ecx.operand_field(down, field.index() as u64).unwrap(); // and finally move back to the const world, always normalizing because // this is not called for statics. - op_to_const(&ecx, field).unwrap() + op_to_const(&ecx, field) } // this function uses `unwrap` copiously, because an already validated constant must have valid @@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>( // Now that we validated, turn this into a proper constant. let def_id = cid.instance.def.def_id(); if tcx.is_static(def_id).is_some() || cid.promoted.is_some() { - mplace_to_const(&ecx, mplace) + Ok(mplace_to_const(&ecx, mplace)) } else { - op_to_const(&ecx, mplace.into()) + Ok(op_to_const(&ecx, mplace.into())) } })(); diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs new file mode 100644 index 0000000000000..074014908bad4 --- /dev/null +++ b/src/test/ui/consts/union_constant.rs @@ -0,0 +1,11 @@ +// compile-pass + +union Uninit { + _never_use: *const u8, + uninit: (), +} + +const UNINIT: Uninit = Uninit { uninit: () }; + +fn main() {} + From df05fbf006e90ed4827c385eb9192e4c46de70f4 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 11 Mar 2019 16:39:40 -0700 Subject: [PATCH 042/157] rustc: fix ICE when trait alias has bare Self --- src/librustc/hir/map/mod.rs | 6 ++++-- src/test/ui/issues/issue-59029-1.rs | 8 ++++++++ src/test/ui/issues/issue-59029-1.stderr | 9 +++++++++ src/test/ui/issues/issue-59029-2.rs | 8 ++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-59029-1.rs create mode 100644 src/test/ui/issues/issue-59029-1.stderr create mode 100644 src/test/ui/issues/issue-59029-2.rs diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 86b6805cc9b4c..0e83ce009c943 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -541,7 +541,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_owner(&self, id: HirId) -> HirId { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id, + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id, Node::GenericParam(_) => self.get_parent_node_by_hir_id(id), _ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id)) } @@ -549,7 +550,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_name(&self, id: HirId) -> Name { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(), + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(), Node::GenericParam(param) => param.name.ident().name, _ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)), } diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs new file mode 100644 index 0000000000000..e98a4d0e491a3 --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where Self::Res: Svc; +//~^ ERROR associated type `Res` not found for `Self` + +fn main() {} diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr new file mode 100644 index 0000000000000..ed1d98c40d18a --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Res` not found for `Self` + --> $DIR/issue-59029-1.rs:5:46 + | +LL | trait MkSvc = Svc where Self::Res: Svc; + | ^^^^^^^^^ associated type `Res` not found + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs new file mode 100644 index 0000000000000..2bdb128d8c4c8 --- /dev/null +++ b/src/test/ui/issues/issue-59029-2.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where >::Res: Svc; + +fn main() {} From 795d307f10ec0fd3851b18a3365755d76b7403e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 14:57:13 -0700 Subject: [PATCH 043/157] Suggest return lifetime when there's only one named lifetime --- src/librustc/middle/resolve_lifetime.rs | 37 +++++++++++++++++-- .../ui/suggestions/return-without-lifetime.rs | 8 ++++ .../return-without-lifetime.stderr | 19 ++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/suggestions/return-without-lifetime.rs create mode 100644 src/test/ui/suggestions/return-without-lifetime.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f862b690f8806..35bca04d1e623 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2298,6 +2298,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; let mut scope = self.scope; + let mut lifetime_names = FxHashSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2310,7 +2311,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Elision { ref elide, .. } => { + Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { Elide::FreshLateAnon(ref counter) => { for lifetime_ref in lifetime_refs { @@ -2320,7 +2321,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } Elide::Exact(l) => l.shifted(late_depth), - Elide::Error(ref e) => break Some(e), + Elide::Error(ref e) => { + if let Scope::Binder { ref lifetimes, .. } = s { + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } + } + break Some(e); + } }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2343,7 +2353,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + add_missing_lifetime_specifiers_label( + &mut err, + span, + lifetime_refs.len(), + &lifetime_names, + self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + ); } err.emit(); @@ -2884,10 +2900,23 @@ fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, span: Span, count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); + } else if let (1, Some(name), Some("&")) = ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet, + ) { + err.span_suggestion( + span, + &format!("consider using the named lifetime `{}`", name), + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, "expected lifetime parameter"); - }; + } } diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 0000000000000..5f19e93013acf --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,8 @@ +struct Thing<'a>(&'a ()); + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr new file mode 100644 index 0000000000000..72f1c142d028f --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -0,0 +1,19 @@ +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:3:34 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:35 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. From f9234767e4ff9b682437464efc9a6ff59db4cff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 15:34:16 -0700 Subject: [PATCH 044/157] review comments --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/test/ui/suggestions/return-without-lifetime.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 35bca04d1e623..d03268df5e148 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2912,7 +2912,7 @@ fn add_missing_lifetime_specifiers_label( ) { err.span_suggestion( span, - &format!("consider using the named lifetime `{}`", name), + "consider using the named lifetime", format!("&{} ", name), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 72f1c142d028f..1ffe91bce05a5 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:3:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:5:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from From adbd0a66457159ffcdd02ee0b553581298968847 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 12 Mar 2019 16:09:20 -0700 Subject: [PATCH 045/157] Make std time tests more robust for platform differences --- src/libstd/time.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6d7093ac33ea7..4c86f70ad871d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -712,13 +712,6 @@ mod tests { assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - // A difference of 80 and 800 years cannot fit inside a 32-bit time_t - if !(cfg!(unix) && crate::mem::size_of::() <= 4) { - let eighty_years = second * 60 * 60 * 24 * 365 * 80; - assert_almost_eq!(a - eighty_years + eighty_years, a); - assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); - } - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); @@ -747,8 +740,8 @@ mod tests { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH).unwrap(); - let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); assert_eq!(b - a, Duration::new(1, 0)); From 0ea9b58029bc7c3da3f213eb9e39acdefcf12647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 18:18:24 -0700 Subject: [PATCH 046/157] Suggest adding lifetime to struct field --- src/librustc/middle/resolve_lifetime.rs | 9 ++++++++- src/test/ui/suggestions/return-without-lifetime.rs | 2 ++ .../ui/suggestions/return-without-lifetime.stderr | 12 +++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d03268df5e148..c9ff84ab2f08a 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2306,7 +2306,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, .. } => { + Scope::Binder { s, ref lifetimes, .. } => { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } late_depth += 1; scope = s; } @@ -2323,6 +2329,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Elide::Exact(l) => l.shifted(late_depth), Elide::Error(ref e) => { if let Scope::Binder { ref lifetimes, .. } = s { + // collect named lifetimes for suggestions for name in lifetimes.keys() { if let hir::ParamName::Plain(name) = name { lifetime_names.insert(*name); diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs index 5f19e93013acf..9bfce11be9ea3 100644 --- a/src/test/ui/suggestions/return-without-lifetime.rs +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -1,4 +1,6 @@ struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +//~^ ERROR missing lifetime specifier fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } //~^ ERROR missing lifetime specifier diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 1ffe91bce05a5..7f5ff95938e30 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -1,5 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:3:34 + --> $DIR/return-without-lifetime.rs:2:16 + | +LL | struct Foo<'a>(&usize); + | ^ help: consider using the named lifetime: `&'a` + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` @@ -7,13 +13,13 @@ LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:5:35 + --> $DIR/return-without-lifetime.rs:7:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0106`. From 266ca31f74ae343fc773b88f3bb77b601034babf Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Tue, 12 Mar 2019 21:00:37 -0700 Subject: [PATCH 047/157] Stabilize Range*::contains. --- src/libcore/ops/range.rs | 49 +++++++++++++------------------- src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_errors/lib.rs | 1 - src/librustc_mir/lib.rs | 1 - src/libstd/lib.rs | 2 +- 5 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 998b597d5e113..cb82ad38eb87d 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -67,7 +67,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -91,8 +91,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..5).contains(&2)); @@ -108,7 +106,7 @@ impl> Range { /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -169,7 +167,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -190,8 +188,6 @@ impl> RangeFrom { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..).contains(&2)); @@ -202,7 +198,7 @@ impl> RangeFrom { /// assert!(!(0.0..).contains(&f32::NAN)); /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -272,8 +268,6 @@ impl> RangeTo { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..5).contains(&-1_000_000_000)); @@ -284,7 +278,7 @@ impl> RangeTo { /// assert!(!(..1.0).contains(&f32::NAN)); /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -317,7 +311,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone)] // not Copy -- see #27186 +#[derive(Clone)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { pub(crate) start: Idx, @@ -353,7 +347,8 @@ impl RangeInclusiveEquality for T { impl PartialEq for RangeInclusive { #[inline] fn eq(&self, other: &Self) -> bool { - self.start == other.start && self.end == other.end + self.start == other.start + && self.end == other.end && RangeInclusiveEquality::canonicalized_is_empty(self) == RangeInclusiveEquality::canonicalized_is_empty(other) } @@ -385,7 +380,11 @@ impl RangeInclusive { #[inline] #[rustc_promotable] pub const fn new(start: Idx, end: Idx) -> Self { - Self { start, end, is_empty: None } + Self { + start, + end, + is_empty: None, + } } /// Returns the lower bound of the range (inclusive). @@ -466,8 +465,6 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..=5).contains(&2)); @@ -484,7 +481,7 @@ impl> RangeInclusive { /// assert!(!(0.0..=f32::NAN).contains(&0.0)); /// assert!(!(f32::NAN..=1.0).contains(&1.0)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -593,15 +590,12 @@ impl fmt::Debug for RangeToInclusive { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeToInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..=5).contains(&-1_000_000_000)); @@ -612,7 +606,7 @@ impl> RangeToInclusive { /// assert!(!(..=1.0).contains(&f32::NAN)); /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -714,14 +708,11 @@ pub trait RangeBounds { #[stable(feature = "collections_range", since = "1.28.0")] fn end_bound(&self) -> Bound<&T>; - /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (3..5).contains(&4)); @@ -731,7 +722,7 @@ pub trait RangeBounds { /// assert!(!(0.0..1.0).contains(&f32::NAN)); /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where T: PartialOrd, @@ -741,9 +732,7 @@ pub trait RangeBounds { Included(ref start) => *start <= item, Excluded(ref start) => *start < item, Unbounded => true, - }) - && - (match self.end_bound() { + }) && (match self.end_bound() { Included(ref end) => item <= *end, Excluded(ref end) => item < *end, Unbounded => true, @@ -819,7 +808,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (Included(ref start), _) => Included(start), (Excluded(ref start), _) => Excluded(start), - (Unbounded, _) => Unbounded, + (Unbounded, _) => Unbounded, } } @@ -827,7 +816,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (_, Included(ref end)) => Included(end), (_, Excluded(ref end)) => Excluded(end), - (_, Unbounded) => Unbounded, + (_, Unbounded) => Unbounded, } } } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7b2b9ec24ea0f..b396c6b54db3f 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -15,7 +15,6 @@ #![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(optin_builtin_traits)] #![feature(concat_idents)] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7c7698ddd3d73..6b4b437930d26 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -2,7 +2,6 @@ #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 0b735b4b39cf5..c45e694ebf832 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(const_fn)] #![feature(decl_macro)] #![feature(exhaustive_patterns)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_attrs)] #![feature(never_type)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e31680f23f1da..307e0c63f3415 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -221,7 +221,7 @@ #![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, + feature(global_asm, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] // std is implemented with unstable features, many of which are internal From 9d938f69362e9568c14955d7df801c21a2266e66 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 13 Mar 2019 12:38:10 +0100 Subject: [PATCH 048/157] Add test for #55809. This commit adds a regression test for #55809 which checks that a overflow does not occur when evaluating a requirement for async functions and `&mut` arguments in some specific circumstances. --- src/test/run-pass/issue-55809.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/run-pass/issue-55809.rs diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs new file mode 100644 index 0000000000000..86b0977bebe1d --- /dev/null +++ b/src/test/run-pass/issue-55809.rs @@ -0,0 +1,30 @@ +// edition:2018 +// run-pass + +#![feature(async_await, await_macro, futures_api)] + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad(v: T) -> u8 where T: Foo { + await!(foo_async(v)) +} + +async fn async_main() { + let mut v = (); + + let _ = await!(bad(&mut v)); + let _ = await!(foo_async(&mut v)); + let _ = await!(bad(v)); +} + +fn main() { + let _ = async_main(); +} From 311025e6a5aad80d028f0771970c43cb4ed025a8 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 7 Mar 2019 18:30:26 +0100 Subject: [PATCH 049/157] Fix generic argument lookup for Self Rewrite the SelfCtor early and use the replacement Def when calculating the path_segs. Note that this also changes which def is seen by the code that computes user_self_ty and is_alias_variant_ctor; I don't see a immediate issue with that, but I'm not 100% clear on the implications. Fixes #57924 --- src/librustc_typeck/check/mod.rs | 119 ++++++++++++------------ src/test/run-pass/issues/issue-57924.rs | 9 ++ 2 files changed, 69 insertions(+), 59 deletions(-) create mode 100644 src/test/run-pass/issues/issue-57924.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 301d7d3ac5623..7dfe9f40d318f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5302,6 +5302,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(original_span.with_lo(original_span.hi() - BytePos(1))) } + // Rewrite `SelfCtor` to `StructCtor` + pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) { + let tcx = self.tcx; + if let Def::SelfCtor(impl_def_id) = def { + let ty = self.impl_self_ty(span, impl_def_id).ty; + let adt_def = ty.ty_adt_def(); + + match adt_def { + Some(adt_def) if adt_def.has_ctor() => { + let variant = adt_def.non_enum_variant(); + let def = Def::StructCtor(variant.did, variant.ctor_kind); + (def, variant.did, tcx.type_of(variant.did)) + } + _ => { + let mut err = tcx.sess.struct_span_err(span, + "the `Self` constructor can only be used with tuple or unit structs"); + if let Some(adt_def) = adt_def { + match adt_def.adt_kind() { + AdtKind::Enum => { + err.help("did you mean to use one of the enum's variants?"); + }, + AdtKind::Struct | + AdtKind::Union => { + err.span_suggestion( + span, + "use curly brackets", + String::from("Self { /* fields */ }"), + Applicability::HasPlaceholders, + ); + } + } + } + err.emit(); + + (def, impl_def_id, tcx.types.err) + } + } + } else { + let def_id = def.def_id(); + + // The things we are substituting into the type should not contain + // escaping late-bound regions, and nor should the base type scheme. + let ty = tcx.type_of(def_id); + (def, def_id, ty) + } + } + // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5321,6 +5368,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; + match def { + Def::Local(nid) | Def::Upvar(nid, ..) => { + let hid = self.tcx.hir().node_to_hir_id(nid); + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, def); + } + _ => {} + } + + let (def, def_id, ty) = self.rewrite_self_ctor(def, span); let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; @@ -5382,17 +5441,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty = None; } - match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, def); - } - _ => {} - } - // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user // did not provide any types, then we want to substitute inference @@ -5425,53 +5473,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.generics_of(*def_id).has_self }).unwrap_or(false); - let mut new_def = def; - let (def_id, ty) = match def { - Def::SelfCtor(impl_def_id) => { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - - match adt_def { - Some(adt_def) if adt_def.has_ctor() => { - let variant = adt_def.non_enum_variant(); - new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, tcx.type_of(variant.did)) - } - _ => { - let mut err = tcx.sess.struct_span_err(span, - "the `Self` constructor can only be used with tuple or unit structs"); - if let Some(adt_def) = adt_def { - match adt_def.adt_kind() { - AdtKind::Enum => { - err.help("did you mean to use one of the enum's variants?"); - }, - AdtKind::Struct | - AdtKind::Union => { - err.span_suggestion( - span, - "use curly brackets", - String::from("Self { /* fields */ }"), - Applicability::HasPlaceholders, - ); - } - } - } - err.emit(); - - (impl_def_id, tcx.types.err) - } - } - } - _ => { - let def_id = def.def_id(); - - // The things we are substituting into the type should not contain - // escaping late-bound regions, and nor should the base type scheme. - let ty = tcx.type_of(def_id); - (def_id, ty) - } - }; - let substs = AstConv::create_substs_for_generic_args( tcx, def_id, @@ -5587,7 +5588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted); self.write_substs(hir_id, substs); - (ty_substituted, new_def) + (ty_substituted, def) } fn check_rustc_args_require_const(&self, diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs new file mode 100644 index 0000000000000..232596334b0ed --- /dev/null +++ b/src/test/run-pass/issues/issue-57924.rs @@ -0,0 +1,9 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) + } +} + +fn main() {} From c37dab7df82e38788648044017ba6dc48c240776 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 13 Mar 2019 07:39:07 -0700 Subject: [PATCH 050/157] Revert "Don't generate minification variable if minification disabled" Fixes #59157 This reverts commit b5ae4d58883151a977487de86856d9529df9d948. --- src/librustdoc/html/render.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d711e4514a049..5109e775ebf81 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1117,11 +1117,7 @@ themePicker.onblur = handleThemeButtonsBlur; // with rustdoc running in parallel. all_indexes.sort(); let mut w = try_err!(File::create(&dst), &dst); - if options.enable_minification { - try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); - } else { - try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst); - } + try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); try_err!(write_minify_replacer(&mut w, &format!("{}\n{}", variables.join(""), all_indexes.join("\n")), options.enable_minification), From 4543245621ee788e52fe3c4f9e3a008eba9f80b1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 12 Mar 2019 13:34:47 -0700 Subject: [PATCH 051/157] Update cargo --- Cargo.lock | 6 +++--- src/tools/cargo | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39ecc880097e3..27f7f59165b1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,7 +251,7 @@ dependencies = [ "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1009,7 +1009,7 @@ dependencies = [ [[package]] name = "glob" -version = "0.2.11" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4083,7 +4083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" diff --git a/src/tools/cargo b/src/tools/cargo index 95b45eca19ac7..0e35bd8af0ec7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 95b45eca19ac785263fed98ecefe540bb47337ac +Subproject commit 0e35bd8af0ec72d3225c4819b330b94628f0e9d0 From 5abd6d9492e8a5a4592bca4c18e1de6104b1ea51 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sun, 10 Mar 2019 21:01:53 -0400 Subject: [PATCH 052/157] add suggestions to invalid macro item error --- src/libsyntax/parse/parser.rs | 45 ++++++++++--------- src/test/ui/issues/issue-10536.rs | 2 +- src/test/ui/issues/issue-10536.stderr | 10 ++++- .../ui/parser/macros-no-semicolon-items.rs | 11 +++++ .../parser/macros-no-semicolon-items.stderr | 41 ++++++++++++++++- 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe31311094b89..22af7d47fd0a1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - let msg = "macros that expand to items must either \ - be surrounded with braces or followed by a semicolon"; - self.span_err(self.prev_span, msg); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } (ident, ast::MacroDef { tokens: tokens, legacy: true }) @@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> { // if it has a special ident, it's definitely an item // // Require a semicolon or braces. - if style != MacStmtStyle::Braces { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must \ - either be surrounded with braces or \ - followed by a semicolon"); - } + if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let span = lo.to(hi); Stmt { @@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> { }; // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must either \ - be surrounded with braces or followed by \ - a semicolon"); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; @@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> { } } } + + fn report_invalid_macro_expansion_item(&self) { + self.struct_span_err( + self.prev_span, + "macros that expand to items must be delimited with braces or followed by a semicolon", + ).multipart_suggestion( + "change the delimiters to curly braces", + vec![ + (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")), + (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()), + ], + Applicability::MaybeIncorrect, + ).span_suggestion( + self.sess.source_map.next_point(self.prev_span), + "add a semicolon", + ';'.to_string(), + Applicability::MaybeIncorrect, + ).emit(); + } } pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, handler: &errors::Handler) { diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index 95c8c2b0585b6..ceb44ecf7f583 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -12,7 +12,7 @@ pub fn main() { foo!(); assert!({one! two()}); - //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a + //~^ ERROR macros that expand to items //~| ERROR cannot find macro `one!` in this scope //~| ERROR mismatched types diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index d5caf777cd45e..584cdf43a8f4b 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,8 +1,16 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/issue-10536.rs:14:22 | LL | assert!({one! two()}); | ^^ +help: change the delimiters to curly braces + | +LL | assert!({one! two {}}); + | ^^ +help: add a semicolon + | +LL | assert!({one! two();}); + | ^ error: expected `(` or `{`, found `}` --> $DIR/issue-10536.rs:21:22 diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs index a727cafcab023..3afc275d61a2b 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.rs +++ b/src/test/ui/parser/macros-no-semicolon-items.rs @@ -1,4 +1,15 @@ macro_rules! foo() //~ ERROR semicolon + //~| ERROR unexpected end of macro + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) fn main() { } diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr index a869a53c1eee2..5276aa6f5e9e9 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.stderr +++ b/src/test/ui/parser/macros-no-semicolon-items.stderr @@ -1,8 +1,45 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/macros-no-semicolon-items.rs:1:17 | LL | macro_rules! foo() | ^^ +help: change the delimiters to curly braces + | +LL | macro_rules! foo {} + | ^^ +help: add a semicolon + | +LL | macro_rules! foo(); + | ^ + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ +help: change the delimiters to curly braces + | +LL | bar! { +LL | blah +LL | blah +LL | blah +LL | } + | +help: add a semicolon + | +LL | ); + | ^ + +error: unexpected end of macro invocation + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments -error: aborting due to previous error +error: aborting due to 3 previous errors From 880b041f3cfc03443d4b4723f0b0cba565ee6177 Mon Sep 17 00:00:00 2001 From: JonathanS Date: Wed, 17 Oct 2018 22:13:21 +0200 Subject: [PATCH 053/157] Enable dist-x86_64-musl as a host architexture --- src/ci/docker/dist-x86_64-musl/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 06f8a2fbba836..e6ffac4019946 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -41,6 +41,8 @@ ENV RUST_CONFIGURE_ARGS \ # See: https://github.com/rust-lang/rust/issues/34978 ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no +ENV HOSTS=x86_64-unknown-linux-musl + ENV SCRIPT \ - python2.7 ../x.py test --target x86_64-unknown-linux-musl && \ - python2.7 ../x.py dist --target x86_64-unknown-linux-musl + python2.7 ../x.py test --host $HOSTS --target $HOSTS && \ + python2.7 ../x.py dist --host $HOSTS --target $HOSTS From 3729e48bf2c6bc45b3efdee56ec2ce2cbcffe900 Mon Sep 17 00:00:00 2001 From: Jonathan Sieber Date: Thu, 18 Oct 2018 21:47:26 +0200 Subject: [PATCH 054/157] Set RUSTFLAGS env to make dylib work The musl-target doesn't automatically disable static linking of musl when building a dylib, and then complains it can't build a dylib. As a workaround, disable static linking via RUSTFLAGS, to see how far the build gets. The proper fix is to have rustc figure that out automagically. --- src/ci/docker/dist-x86_64-musl/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index e6ffac4019946..441c2e7c57a07 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -43,6 +43,8 @@ ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no ENV HOSTS=x86_64-unknown-linux-musl +ENV RUSTFLAGS="-C target-feature=-crt-static" + ENV SCRIPT \ python2.7 ../x.py test --host $HOSTS --target $HOSTS && \ python2.7 ../x.py dist --host $HOSTS --target $HOSTS From aecb32ce6e80862562a728a6bee7b741b299d988 Mon Sep 17 00:00:00 2001 From: Jonathan Sieber Date: Fri, 19 Oct 2018 19:04:33 +0000 Subject: [PATCH 055/157] build a proper c++-enabled musl toolchain with musl-cross-make --- src/ci/docker/dist-x86_64-musl/Dockerfile | 22 ++++---- src/ci/docker/scripts/musl-toolchain.sh | 66 +++++++++++++++++++++++ 2 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 src/ci/docker/scripts/musl-toolchain.sh diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 441c2e7c57a07..2f538a28b4364 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ make \ file \ + wget \ curl \ ca-certificates \ python2.7 \ @@ -18,19 +19,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ WORKDIR /build/ -COPY scripts/musl.sh /build/ +COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well -RUN CC=gcc \ - CFLAGS="-Wa,-mrelax-relocations=no" \ - CXX=g++ \ - CXXFLAGS="-Wa,-mrelax-relocations=no" \ - bash musl.sh x86_64 && rm -rf /build +# TODO: Check what this issue is and if we can ignore it + +RUN bash musl-toolchain.sh x86_64-linux-musl && rm -rf build COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ - --musl-root-x86_64=/musl-x86_64 \ + --musl-root-x86_64=/usr/local/x86_64-linux-musl \ --enable-extended \ --disable-docs @@ -39,9 +38,14 @@ ENV RUST_CONFIGURE_ARGS \ # way to produce "super compatible" binaries. # # See: https://github.com/rust-lang/rust/issues/34978 -ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no +#ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no + +ENV HOSTS=x86_64-unknown-linux-musl \ + CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ + CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ -ENV HOSTS=x86_64-unknown-linux-musl +# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER=musl-gcc \ +# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="qemu-arm -L /musl-arm" ENV RUSTFLAGS="-C target-feature=-crt-static" diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh new file mode 100644 index 0000000000000..db609a8666f30 --- /dev/null +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -0,0 +1,66 @@ +# Copyright 2016 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + rm /tmp/build.log + set -x +} + +TARGET=$1 +OUTPUT=/usr/local +shift + +git clone https://github.com/richfelker/musl-cross-make -b v0.9.7 +cd musl-cross-make + +hide_output make -j$(nproc) TARGET=$TARGET +hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT + +cd .. + +export CC=$TARGET-gcc +export CXX=$TARGET-g++ + +LLVM=60 + +# may have been downloaded in a previous run +if [ ! -d libunwind-release_$LLVM ]; then + curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf - + curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf - +fi + +mkdir libunwind-build +cd libunwind-build +cmake ../libunwind-release_$LLVM \ + -DLLVM_PATH=/build/llvm-release_$LLVM \ + -DLIBUNWIND_ENABLE_SHARED=0 \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_C_FLAGS="$CFLAGS" \ + -DCMAKE_CXX_FLAGS="$CXXFLAGS" + +hide_output make -j$(nproc) +cp lib/libunwind.a $OUTPUT/$TARGET/lib +cd ../ && rm -rf libunwind-build + From 8e2aa524ed47a8a797141ff47f6bcc5242caa270 Mon Sep 17 00:00:00 2001 From: Jonathan Sieber Date: Fri, 19 Oct 2018 20:28:34 +0000 Subject: [PATCH 056/157] Make the musl dynamic loader known to the system, so it can execute target binaries --- src/ci/docker/scripts/musl-toolchain.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index db609a8666f30..0406d5182e8f6 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -28,6 +28,10 @@ exit 1 } TARGET=$1 +#ARCH=$1 +#TARGET=linux-musl-$ARCH +ARCH=x86_64 + OUTPUT=/usr/local shift @@ -39,6 +43,13 @@ hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT cd .. +# Make musl binaries executable + +ln -s $OUTPUT/$TARGET/lib/ld-musl-$ARCH.so.1 /lib +ln -s $OUTPUT/$TARGET/lib/libc.so /lib +echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path + + export CC=$TARGET-gcc export CXX=$TARGET-g++ From 3f107fd43a32b76da558855a5793bc922ef1fac8 Mon Sep 17 00:00:00 2001 From: Jonathan Sieber Date: Tue, 27 Nov 2018 20:56:34 +0100 Subject: [PATCH 057/157] musl-toolchain: fix global lib paths (dont create /lib/libc.so) --- src/ci/docker/scripts/musl-toolchain.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 0406d5182e8f6..25781c747493a 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -45,8 +45,7 @@ cd .. # Make musl binaries executable -ln -s $OUTPUT/$TARGET/lib/ld-musl-$ARCH.so.1 /lib -ln -s $OUTPUT/$TARGET/lib/libc.so /lib +ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1 echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path From 52a3311dc9b5350536851baaa30ee6240374b5e9 Mon Sep 17 00:00:00 2001 From: Martell Malone Date: Sat, 5 Jan 2019 12:59:46 -0800 Subject: [PATCH 058/157] Address review comments --- src/ci/docker/scripts/musl-toolchain.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 25781c747493a..11954b82b8444 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -41,7 +41,7 @@ cd musl-cross-make hide_output make -j$(nproc) TARGET=$TARGET hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT -cd .. +cd - # Make musl binaries executable @@ -72,5 +72,5 @@ cmake ../libunwind-release_$LLVM \ hide_output make -j$(nproc) cp lib/libunwind.a $OUTPUT/$TARGET/lib -cd ../ && rm -rf libunwind-build +cd - && rm -rf libunwind-build From cacb3053e86f7c3f6eb60e6e25f8bb888d809ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 11 Jan 2019 18:45:37 +0100 Subject: [PATCH 059/157] musl: update LLVM to 7 --- src/ci/docker/scripts/musl-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 11954b82b8444..45bca4bfdfe48 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -52,7 +52,7 @@ echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path export CC=$TARGET-gcc export CXX=$TARGET-g++ -LLVM=60 +LLVM=70 # may have been downloaded in a previous run if [ ! -d libunwind-release_$LLVM ]; then From cbc1ce0b840830a7a390716bc8be435457892436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Sat, 10 Feb 2018 14:03:13 +0100 Subject: [PATCH 060/157] Drop copyright notice from musl-toolchain --- src/ci/docker/scripts/musl-toolchain.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 45bca4bfdfe48..00b6a113da105 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -1,13 +1,3 @@ -# Copyright 2016 The Rust Project Developers. See the COPYRIGHT -# file at the top-level directory of this distribution and at -# http://rust-lang.org/COPYRIGHT. -# -# Licensed under the Apache License, Version 2.0 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - set -ex hide_output() { From 4dd57efae294a13a132b97325e7e89bc763e85e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 4 Mar 2019 14:00:05 +0100 Subject: [PATCH 061/157] Disable relax relocations again --- src/ci/docker/dist-x86_64-musl/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 2f538a28b4364..3a95bfd6ef485 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -22,8 +22,9 @@ WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well # TODO: Check what this issue is and if we can ignore it - -RUN bash musl-toolchain.sh x86_64-linux-musl && rm -rf build +RUN CFLAGS="-Wa,-mrelax-relocations=no" \ + CXXFLAGS="-Wa,-mrelax-relocations=no" \ + bash musl-toolchain.sh x86_64-linux-musl && rm -rf build COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -38,7 +39,7 @@ ENV RUST_CONFIGURE_ARGS \ # way to produce "super compatible" binaries. # # See: https://github.com/rust-lang/rust/issues/34978 -#ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no +ENV CFLAGS_x86_64_unknown_linux_musl=-Wa,-mrelax-relocations=no ENV HOSTS=x86_64-unknown-linux-musl \ CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ From 66de5c6e90ff3975bcef01de90bac82a8e92fc8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Tue, 12 Mar 2019 17:15:03 +0100 Subject: [PATCH 062/157] Move testing to test-various --- src/ci/docker/dist-x86_64-musl/Dockerfile | 4 +--- src/ci/docker/test-various/Dockerfile | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 3a95bfd6ef485..543b9377357fa 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -50,6 +50,4 @@ ENV HOSTS=x86_64-unknown-linux-musl \ ENV RUSTFLAGS="-C target-feature=-crt-static" -ENV SCRIPT \ - python2.7 ../x.py test --host $HOSTS --target $HOSTS && \ - python2.7 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index 6c419e13c9f05..f70ea9da92e73 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -11,7 +11,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ - xz-utils + xz-utils \ + # for musl + wget \ + patch # FIXME: build the `ptx-linker` instead. RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.2/rust-ptx-linker.linux64.tar.gz | \ @@ -20,10 +23,18 @@ RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-a RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \ tar -xJ +WORKDIR /build/ +COPY scripts/musl-toolchain.sh /build/ +RUN CFLAGS="-Wa,-mrelax-relocations=no" \ + CXXFLAGS="-Wa,-mrelax-relocations=no" \ + bash musl-toolchain.sh x86_64-linux-musl && rm -rf build +WORKDIR / + COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ + --musl-root-x86_64=/usr/local/x86_64-linux-musl \ --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \ --set rust.lld @@ -47,4 +58,9 @@ ENV NVPTX_TARGETS=nvptx64-nvidia-cuda ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \ src/test/run-make -ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT +ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ + CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ + CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ +ENV MUSL_SCRIPT python2.7 /checkout/x.py test --target $MUSL_TARGETS + +ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT From 17464a7b877c83cb506ccac33347a6c777b78159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 13 Mar 2019 22:18:13 +0100 Subject: [PATCH 063/157] Final cleanups --- src/ci/docker/dist-x86_64-musl/Dockerfile | 8 +++----- src/ci/docker/scripts/musl-toolchain.sh | 10 ++++------ src/ci/docker/test-various/Dockerfile | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 543b9377357fa..560df2f3a5700 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -21,10 +21,9 @@ WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well -# TODO: Check what this issue is and if we can ignore it RUN CFLAGS="-Wa,-mrelax-relocations=no" \ CXXFLAGS="-Wa,-mrelax-relocations=no" \ - bash musl-toolchain.sh x86_64-linux-musl && rm -rf build + bash musl-toolchain.sh x86_64 && rm -rf build COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -45,9 +44,8 @@ ENV HOSTS=x86_64-unknown-linux-musl \ CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ -# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER=musl-gcc \ -# CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="qemu-arm -L /musl-arm" - +# Musl defaults to static libs but we need them to be dynamic for host toolchain. +# The toolchain will produce static libs by default. ENV RUSTFLAGS="-C target-feature=-crt-static" ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 00b6a113da105..7802e15f18840 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -17,10 +17,8 @@ exit 1 set -x } -TARGET=$1 -#ARCH=$1 -#TARGET=linux-musl-$ARCH -ARCH=x86_64 +ARCH=$1 +TARGET=linux-musl-$ARCH OUTPUT=/usr/local shift @@ -33,8 +31,7 @@ hide_output make install TARGET=$TARGET OUTPUT=$OUTPUT cd - -# Make musl binaries executable - +# Install musl library to make binaries executable ln -s $OUTPUT/$TARGET/lib/libc.so /lib/ld-musl-$ARCH.so.1 echo $OUTPUT/$TARGET/lib >> /etc/ld-musl-$ARCH.path @@ -50,6 +47,7 @@ if [ ! -d libunwind-release_$LLVM ]; then curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf - fi +# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089 mkdir libunwind-build cd libunwind-build cmake ../libunwind-release_$LLVM \ diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index f70ea9da92e73..80c6ed68cb547 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -27,7 +27,7 @@ WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ RUN CFLAGS="-Wa,-mrelax-relocations=no" \ CXXFLAGS="-Wa,-mrelax-relocations=no" \ - bash musl-toolchain.sh x86_64-linux-musl && rm -rf build + bash musl-toolchain.sh x86_64 && rm -rf build WORKDIR / COPY scripts/sccache.sh /scripts/ From fe30743c79018b2a73151440f5d8948d0979ac62 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Tue, 12 Mar 2019 00:49:17 +0000 Subject: [PATCH 064/157] Moved issue tests to subdirs and normalised names. --- .../{issue13213aux.rs => issue-13213-aux.rs} | 0 src/test/debuginfo/issue-13213.rs | 6 ++-- ..._macro_def.rs => issue-49482-macro-def.rs} | 0 ...82_reexport.rs => issue-49482-reexport.rs} | 0 .../{issue_54059.rs => issue-54059.rs} | 0 src/test/incremental/issue-49482.rs | 4 +-- .../{issue_49595.rs => issue-49595.rs} | 0 src/test/incremental/issue-54059.rs | 2 +- .../{issue_12590_a.rs => issue-12590-a.rs} | 1 + src/test/pretty/issue-12590-b.rs | 5 ++++ .../{issue_12590_c.pp => issue-12590-c.pp} | 3 +- .../{issue_12590_c.rs => issue-12590-c.rs} | 3 +- src/test/pretty/issue_12590_b.rs | 4 --- ...tial_eq.rs => custom-derive-partial-eq.rs} | 0 ...n_attr.rs => custom-derive-plugin-attr.rs} | 0 ...rive_plugin.rs => custom-derive-plugin.rs} | 0 .../{issue_24106.rs => issue-24106.rs} | 0 .../{lint_for_crate.rs => lint-for-crate.rs} | 0 ...lvm_pass_plugin.rs => llvm-pass-plugin.rs} | 0 ...acro_crate_test.rs => macro-crate-test.rs} | 0 .../{plugin_args.rs => plugin-args.rs} | 0 .../{roman_numerals.rs => roman-numerals.rs} | 0 ...rs => syntax-extension-with-dll-deps-1.rs} | 0 .../custom-derive-partial-eq.rs | 2 +- .../run-pass-fulldeps/derive-totalsum-attr.rs | 2 +- src/test/run-pass-fulldeps/derive-totalsum.rs | 2 +- .../run-pass-fulldeps/issue-15778-pass.rs | 2 +- .../{issue_24106.rs => issue-24106.rs} | 2 +- src/test/run-pass-fulldeps/issue-40663.rs | 2 +- .../run-pass-fulldeps/llvm-pass-plugin.rs | 2 +- .../macro-crate-multi-decorator.rs | 2 +- src/test/run-pass-fulldeps/plugin-args-1.rs | 2 +- src/test/run-pass-fulldeps/plugin-args-2.rs | 2 +- src/test/run-pass-fulldeps/plugin-args-3.rs | 2 +- .../run-pass-fulldeps/roman-numerals-macro.rs | 2 +- .../{rmeta_rlib.rs => rmeta-rlib.rs} | 0 .../{rmeta_rmeta.rs => rmeta-rmeta.rs} | 0 ...{issue_10031_aux.rs => issue-10031-aux.rs} | 0 .../{issue_12612_1.rs => issue-12612-1.rs} | 0 .../{issue_12612_2.rs => issue-12612-2.rs} | 0 .../{issue13507.rs => issue-13507.rs} | 0 .../{issue_19293.rs => issue-19293.rs} | 0 .../{issue_20389.rs => issue-20389.rs} | 0 .../{issue2170lib.rs => issue-2170-lib.rs} | 0 .../{issue_2316_a.rs => issue-2316-a.rs} | 0 .../{issue_2316_b.rs => issue-2316-b.rs} | 0 .../{issue_2472_b.rs => issue-2472-b.rs} | 0 .../{issue_2723_a.rs => issue-2723-a.rs} | 0 .../{issue_3136_a.rc => issue-3136-a.rc} | 1 + .../{issue_3136_a.rs => issue-3136-a.rs} | 0 .../{issue34796aux.rs => issue-34796-aux.rs} | 0 .../{issue_38190.rs => issue-38190.rs} | 0 ...{issue_38226_aux.rs => issue-38226-aux.rs} | 0 ..._38715-modern.rs => issue-38715-modern.rs} | 0 .../{issue_38715.rs => issue-38715.rs} | 0 ...ue_3979_traits.rs => issue-3979-traits.rs} | 0 .../{issue_39823.rs => issue-39823.rs} | 0 .../{issue_40469.rs => issue-40469.rs} | 0 .../{issue_41053.rs => issue-41053.rs} | 0 .../{issue_42007_s.rs => issue-42007-s.rs} | 0 .../{issue_8401.rs => issue-8401.rs} | 0 .../{issue_9123.rs => issue-9123.rs} | 0 .../{issue_9155.rs => issue-9155.rs} | 0 .../{issue_9188.rs => issue-9188.rs} | 0 src/test/run-pass/issues/issue-10031.rs | 2 +- src/test/run-pass/issues/issue-12612.rs | 4 +-- src/test/run-pass/issues/issue-13507-2.rs | 10 +++---- src/test/run-pass/{ => issues}/issue-18952.rs | 0 src/test/run-pass/issues/issue-19293.rs | 2 +- src/test/run-pass/issues/issue-20389.rs | 2 +- src/test/run-pass/issues/issue-2170-exe.rs | 9 ++++++ src/test/run-pass/issues/issue-2316-c.rs | 4 +-- .../auxiliary/issue-24687-lib.rs} | 5 ++-- .../issue-24687-mbcs-in-comments.rs} | 0 .../main.rs | 6 ++-- src/test/run-pass/issues/issue-2472.rs | 2 +- .../run-pass/issues/issue-26873-multifile.rs | 3 +- .../A/B.rs | 0 .../A/C.rs | 0 .../A/mod.rs | 0 .../compiletest-ignore-dir | 0 .../mod.rs | 0 src/test/run-pass/issues/issue-2723-b.rs | 2 +- ...rk-ex1.rs => issue-28498-must-work-ex1.rs} | 0 ...rk-ex2.rs => issue-28498-must-work-ex2.rs} | 0 ...98-ugeh-ex1.rs => issue-28498-ugeh-ex1.rs} | 0 ...> issue-28498-ugeh-with-lifetime-param.rs} | 0 ... => issue-28498-ugeh-with-passed-to-fn.rs} | 0 ...s => issue-28498-ugeh-with-trait-bound.rs} | 0 .../{issue29927-1.rs => issue-29927-1.rs} | 0 .../{issue_3136_b.rs => issue-3136-b.rs} | 3 +- src/test/run-pass/issues/issue-34796.rs | 6 ++-- src/test/run-pass/issues/issue-38190.rs | 7 +++-- src/test/run-pass/issues/issue-38226.rs | 2 +- src/test/run-pass/issues/issue-38715.rs | 4 +-- src/test/run-pass/issues/issue-3979-xcrate.rs | 2 +- src/test/run-pass/issues/issue-39823.rs | 2 +- src/test/run-pass/issues/issue-40469.rs | 2 +- src/test/run-pass/issues/issue-41053.rs | 2 +- src/test/run-pass/issues/issue-42007.rs | 2 +- src/test/run-pass/{ => issues}/issue-45510.rs | 0 src/test/run-pass/{ => issues}/issue-48006.rs | 0 src/test/run-pass/{ => issues}/issue-53728.rs | 0 src/test/run-pass/{ => issues}/issue-53843.rs | 0 ...issue-54462-mutable-noalias-correctness.rs | 0 src/test/run-pass/{ => issues}/issue-54467.rs | 0 src/test/run-pass/{ => issues}/issue-55376.rs | 0 src/test/run-pass/{ => issues}/issue-55380.rs | 0 src/test/run-pass/{ => issues}/issue-56237.rs | 0 src/test/run-pass/issues/issue-8401.rs | 2 +- src/test/run-pass/issues/issue-9123.rs | 2 +- .../issues/{issue_9155.rs => issue-9155.rs} | 2 +- src/test/run-pass/issues/issue-9188.rs | 2 +- src/test/run-pass/issues/issue2170exe.rs | 9 ------ src/test/run-pass/rmeta.rs | 4 +-- .../{enum_primitive.rs => enum-primitive.rs} | 0 .../{reexp_stripped.rs => reexp-stripped.rs} | 0 src/test/rustdoc/no-stack-overflow-25295.rs | 5 ++-- src/test/rustdoc/redirect.rs | 2 +- ...ttr_plugin_test.rs => attr-plugin-test.rs} | 0 .../{lint_for_crate.rs => lint-for-crate.rs} | 0 ...ugin_test.rs => lint-group-plugin-test.rs} | 0 ...int_plugin_test.rs => lint-plugin-test.rs} | 0 .../{lint_tool_test.rs => lint-tool-test.rs} | 0 ...{rlib_crate_test.rs => rlib-crate-test.rs} | 0 ...cked.rs => dropck-tarena-cycle-checked.rs} | 0 ...err => dropck-tarena-cycle-checked.stderr} | 2 +- ..._drop.rs => dropck-tarena-unsound-drop.rs} | 0 ...derr => dropck-tarena-unsound-drop.stderr} | 2 +- src/test/ui-fulldeps/gated-plugin.rs | 2 +- src/test/ui-fulldeps/issue-15778-fail.rs | 2 +- .../lint-group-plugin-deny-cmdline.rs | 2 +- src/test/ui-fulldeps/lint-group-plugin.rs | 2 +- .../ui-fulldeps/lint-plugin-cmdline-allow.rs | 2 +- .../ui-fulldeps/lint-plugin-cmdline-load.rs | 2 +- src/test/ui-fulldeps/lint-plugin-deny-attr.rs | 2 +- .../ui-fulldeps/lint-plugin-deny-cmdline.rs | 2 +- .../ui-fulldeps/lint-plugin-forbid-attrs.rs | 2 +- .../ui-fulldeps/lint-plugin-forbid-cmdline.rs | 2 +- src/test/ui-fulldeps/lint-plugin.rs | 2 +- ...ne_allow.rs => lint-tool-cmdline-allow.rs} | 7 ++--- ....stderr => lint-tool-cmdline-allow.stderr} | 12 ++++---- .../{lint_tool_test.rs => lint-tool-test.rs} | 2 +- ...tool_test.stderr => lint-tool-test.stderr} | 18 ++++++------ src/test/ui-fulldeps/macro-crate-rlib.rs | 2 +- .../ui-fulldeps/plugin-as-extern-crate.rs | 2 +- .../ui-fulldeps/plugin-attr-register-deny.rs | 2 +- ... => default-ty-param-cross-crate-crate.rs} | 0 .../{define_macro.rs => define-macro.rs} | 0 ...nostics.rs => orphan-check-diagnostics.rs} | 0 ..._and_stability.rs => pub-and-stability.rs} | 0 .../{rmeta_meta.rs => rmeta-meta.rs} | 0 .../{rmeta_rlib.rs => rmeta-rlib.rs} | 0 .../{stability_cfg2.rs => stability-cfg2.rs} | 0 ...method_lib.rs => xc-private-method-lib.rs} | 0 .../{issue_23563_a.rs => issue-23563-a.rs} | 0 src/test/ui/e0119/issue-23563.rs | 2 +- src/test/ui/enable-unstable-lib-feature.rs | 2 +- src/test/ui/explore-issue-38412.rs | 3 +- src/test/ui/{ => issues}/issue-42944.rs | 0 src/test/ui/{ => issues}/issue-42944.stderr | 0 .../issue-53787-inline-assembler-macro.rs | 0 .../issue-53787-inline-assembler-macro.stderr | 0 src/test/ui/{ => issues}/issue-54943-1.rs | 0 src/test/ui/{ => issues}/issue-54943-2.rs | 0 src/test/ui/{ => issues}/issue-54943-3.rs | 0 src/test/ui/{ => issues}/issue-54943.rs | 0 src/test/ui/{ => issues}/issue-54943.stderr | 0 .../ui/{ => issues}/issue-55511.nll.stderr | 0 src/test/ui/{ => issues}/issue-55511.rs | 0 src/test/ui/{ => issues}/issue-55511.stderr | 0 src/test/ui/{ => issues}/issue-55846.rs | 0 ...{issue_56411_aux.rs => issue-56411-aux.rs} | 0 src/test/ui/issues/issue-56411.rs | 5 ++-- src/test/ui/issues/issue-56411.stderr | 12 ++++---- src/test/ui/lint/auxiliary/stability-cfg2.rs | 5 ++++ src/test/ui/lint/lint-stability-deprecated.rs | 2 +- src/test/ui/lint/lint-stability.rs | 2 +- src/test/ui/orphan-check-diagnostics.rs | 5 ++-- src/test/ui/orphan-check-diagnostics.stderr | 2 +- src/test/ui/out-of-order-shadowing.rs | 2 +- .../{issue_38586.rs => issue-38586.rs} | 0 .../{issue_50493.rs => issue-50493.rs} | 0 src/test/ui/proc-macro/issue-38586.rs | 2 +- src/test/ui/proc-macro/issue-50493.rs | 2 +- ...{issue_19452_aux.rs => issue-19452-aux.rs} | 0 .../{issue_3907.rs => issue-3907.rs} | 0 src/test/ui/resolve/issue-19452.rs | 3 +- src/test/ui/resolve/issue-19452.stderr | 4 +-- src/test/ui/resolve/issue-3907-2.rs | 3 +- src/test/ui/resolve/issue-3907-2.stderr | 2 +- src/test/ui/resolve/issue-3907.rs | 3 +- src/test/ui/resolve/issue-3907.stderr | 2 +- src/test/ui/rmeta-lib-pass.rs | 2 +- src/test/ui/rmeta-pass.rs | 2 +- src/test/ui/rmeta_lib.rs | 2 +- src/test/ui/rmeta_meta_main.rs | 2 +- .../auxiliary/use-from-trait-xc.rs} | 0 .../ui/use/auxiliary/use_from_trait_xc.rs | 29 ------------------- src/test/ui/{ => use}/issue-18986.rs | 2 +- src/test/ui/{ => use}/issue-18986.stderr | 0 src/test/ui/use/use-from-trait-xc.rs | 2 +- ...{useless_comment.rs => useless-comment.rs} | 0 ..._comment.stderr => useless-comment.stderr} | 22 +++++++------- src/test/ui/xc-private-method.rs | 2 +- src/test/ui/xc-private-method2.rs | 2 +- 206 files changed, 177 insertions(+), 188 deletions(-) rename src/test/debuginfo/auxiliary/{issue13213aux.rs => issue-13213-aux.rs} (100%) rename src/test/incremental/auxiliary/{issue_49482_macro_def.rs => issue-49482-macro-def.rs} (100%) rename src/test/incremental/auxiliary/{issue_49482_reexport.rs => issue-49482-reexport.rs} (100%) rename src/test/incremental/auxiliary/{issue_54059.rs => issue-54059.rs} (100%) rename src/test/incremental/issue-49595/{issue_49595.rs => issue-49595.rs} (100%) rename src/test/pretty/{issue_12590_a.rs => issue-12590-a.rs} (75%) create mode 100644 src/test/pretty/issue-12590-b.rs rename src/test/pretty/{issue_12590_c.pp => issue-12590-c.pp} (82%) rename src/test/pretty/{issue_12590_c.rs => issue-12590-c.rs} (67%) delete mode 100644 src/test/pretty/issue_12590_b.rs rename src/test/run-pass-fulldeps/auxiliary/{custom_derive_partial_eq.rs => custom-derive-partial-eq.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{custom_derive_plugin_attr.rs => custom-derive-plugin-attr.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{custom_derive_plugin.rs => custom-derive-plugin.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{issue_24106.rs => issue-24106.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{lint_for_crate.rs => lint-for-crate.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{llvm_pass_plugin.rs => llvm-pass-plugin.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{macro_crate_test.rs => macro-crate-test.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{plugin_args.rs => plugin-args.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{roman_numerals.rs => roman-numerals.rs} (100%) rename src/test/run-pass-fulldeps/auxiliary/{syntax_extension_with_dll_deps_1.rs => syntax-extension-with-dll-deps-1.rs} (100%) rename src/test/run-pass-fulldeps/{issue_24106.rs => issue-24106.rs} (71%) rename src/test/run-pass/auxiliary/{rmeta_rlib.rs => rmeta-rlib.rs} (100%) rename src/test/run-pass/auxiliary/{rmeta_rmeta.rs => rmeta-rmeta.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_10031_aux.rs => issue-10031-aux.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_12612_1.rs => issue-12612-1.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_12612_2.rs => issue-12612-2.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue13507.rs => issue-13507.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_19293.rs => issue-19293.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_20389.rs => issue-20389.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue2170lib.rs => issue-2170-lib.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_2316_a.rs => issue-2316-a.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_2316_b.rs => issue-2316-b.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_2472_b.rs => issue-2472-b.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_2723_a.rs => issue-2723-a.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_3136_a.rc => issue-3136-a.rc} (62%) rename src/test/run-pass/issues/auxiliary/{issue_3136_a.rs => issue-3136-a.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue34796aux.rs => issue-34796-aux.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_38190.rs => issue-38190.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_38226_aux.rs => issue-38226-aux.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_38715-modern.rs => issue-38715-modern.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_38715.rs => issue-38715.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_3979_traits.rs => issue-3979-traits.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_39823.rs => issue-39823.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_40469.rs => issue-40469.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_41053.rs => issue-41053.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_42007_s.rs => issue-42007-s.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_8401.rs => issue-8401.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_9123.rs => issue-9123.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_9155.rs => issue-9155.rs} (100%) rename src/test/run-pass/issues/auxiliary/{issue_9188.rs => issue-9188.rs} (100%) rename src/test/run-pass/{ => issues}/issue-18952.rs (100%) create mode 100644 src/test/run-pass/issues/issue-2170-exe.rs rename src/test/run-pass/issues/{issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs => issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs} (62%) rename src/test/run-pass/issues/{issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs => issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs} (100%) rename src/test/run-pass/issues/{issue24687-embed-debuginfo => issue-24687-embed-debuginfo}/main.rs (62%) rename src/test/run-pass/issues/{issue_26873_multifile => issue-26873-multifile}/A/B.rs (100%) rename src/test/run-pass/issues/{issue_26873_multifile => issue-26873-multifile}/A/C.rs (100%) rename src/test/run-pass/issues/{issue_26873_multifile => issue-26873-multifile}/A/mod.rs (100%) rename src/test/run-pass/issues/{issue_26873_multifile => issue-26873-multifile}/compiletest-ignore-dir (100%) rename src/test/run-pass/issues/{issue_26873_multifile => issue-26873-multifile}/mod.rs (100%) rename src/test/run-pass/issues/{issue28498-must-work-ex1.rs => issue-28498-must-work-ex1.rs} (100%) rename src/test/run-pass/issues/{issue28498-must-work-ex2.rs => issue-28498-must-work-ex2.rs} (100%) rename src/test/run-pass/issues/{issue28498-ugeh-ex1.rs => issue-28498-ugeh-ex1.rs} (100%) rename src/test/run-pass/issues/{issue28498-ugeh-with-lifetime-param.rs => issue-28498-ugeh-with-lifetime-param.rs} (100%) rename src/test/run-pass/issues/{issue28498-ugeh-with-passed-to-fn.rs => issue-28498-ugeh-with-passed-to-fn.rs} (100%) rename src/test/run-pass/issues/{issue28498-ugeh-with-trait-bound.rs => issue-28498-ugeh-with-trait-bound.rs} (100%) rename src/test/run-pass/issues/{issue29927-1.rs => issue-29927-1.rs} (100%) rename src/test/run-pass/issues/{issue_3136_b.rs => issue-3136-b.rs} (75%) rename src/test/run-pass/{ => issues}/issue-45510.rs (100%) rename src/test/run-pass/{ => issues}/issue-48006.rs (100%) rename src/test/run-pass/{ => issues}/issue-53728.rs (100%) rename src/test/run-pass/{ => issues}/issue-53843.rs (100%) rename src/test/run-pass/{ => issues}/issue-54462-mutable-noalias-correctness.rs (100%) rename src/test/run-pass/{ => issues}/issue-54467.rs (100%) rename src/test/run-pass/{ => issues}/issue-55376.rs (100%) rename src/test/run-pass/{ => issues}/issue-55380.rs (100%) rename src/test/run-pass/{ => issues}/issue-56237.rs (100%) rename src/test/run-pass/issues/{issue_9155.rs => issue-9155.rs} (83%) delete mode 100644 src/test/run-pass/issues/issue2170exe.rs rename src/test/rustdoc/auxiliary/{enum_primitive.rs => enum-primitive.rs} (100%) rename src/test/rustdoc/auxiliary/{reexp_stripped.rs => reexp-stripped.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{attr_plugin_test.rs => attr-plugin-test.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{lint_for_crate.rs => lint-for-crate.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{lint_group_plugin_test.rs => lint-group-plugin-test.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{lint_plugin_test.rs => lint-plugin-test.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{lint_tool_test.rs => lint-tool-test.rs} (100%) rename src/test/ui-fulldeps/auxiliary/{rlib_crate_test.rs => rlib-crate-test.rs} (100%) rename src/test/ui-fulldeps/{dropck_tarena_cycle_checked.rs => dropck-tarena-cycle-checked.rs} (100%) rename src/test/ui-fulldeps/{dropck_tarena_cycle_checked.stderr => dropck-tarena-cycle-checked.stderr} (88%) rename src/test/ui-fulldeps/{dropck_tarena_unsound_drop.rs => dropck-tarena-unsound-drop.rs} (100%) rename src/test/ui-fulldeps/{dropck_tarena_unsound_drop.stderr => dropck-tarena-unsound-drop.stderr} (89%) rename src/test/ui-fulldeps/{lint_tool_cmdline_allow.rs => lint-tool-cmdline-allow.rs} (66%) rename src/test/ui-fulldeps/{lint_tool_cmdline_allow.stderr => lint-tool-cmdline-allow.stderr} (71%) rename src/test/ui-fulldeps/{lint_tool_test.rs => lint-tool-test.rs} (96%) rename src/test/ui-fulldeps/{lint_tool_test.stderr => lint-tool-test.stderr} (85%) rename src/test/ui/auxiliary/{default_ty_param_cross_crate_crate.rs => default-ty-param-cross-crate-crate.rs} (100%) rename src/test/ui/auxiliary/{define_macro.rs => define-macro.rs} (100%) rename src/test/ui/auxiliary/{orphan_check_diagnostics.rs => orphan-check-diagnostics.rs} (100%) rename src/test/ui/auxiliary/{pub_and_stability.rs => pub-and-stability.rs} (100%) rename src/test/ui/auxiliary/{rmeta_meta.rs => rmeta-meta.rs} (100%) rename src/test/ui/auxiliary/{rmeta_rlib.rs => rmeta-rlib.rs} (100%) rename src/test/ui/auxiliary/{stability_cfg2.rs => stability-cfg2.rs} (100%) rename src/test/ui/auxiliary/{xc_private_method_lib.rs => xc-private-method-lib.rs} (100%) rename src/test/ui/e0119/auxiliary/{issue_23563_a.rs => issue-23563-a.rs} (100%) rename src/test/ui/{ => issues}/issue-42944.rs (100%) rename src/test/ui/{ => issues}/issue-42944.stderr (100%) rename src/test/ui/{ => issues}/issue-53787-inline-assembler-macro.rs (100%) rename src/test/ui/{ => issues}/issue-53787-inline-assembler-macro.stderr (100%) rename src/test/ui/{ => issues}/issue-54943-1.rs (100%) rename src/test/ui/{ => issues}/issue-54943-2.rs (100%) rename src/test/ui/{ => issues}/issue-54943-3.rs (100%) rename src/test/ui/{ => issues}/issue-54943.rs (100%) rename src/test/ui/{ => issues}/issue-54943.stderr (100%) rename src/test/ui/{ => issues}/issue-55511.nll.stderr (100%) rename src/test/ui/{ => issues}/issue-55511.rs (100%) rename src/test/ui/{ => issues}/issue-55511.stderr (100%) rename src/test/ui/{ => issues}/issue-55846.rs (100%) rename src/test/ui/issues/{issue_56411_aux.rs => issue-56411-aux.rs} (100%) create mode 100644 src/test/ui/lint/auxiliary/stability-cfg2.rs rename src/test/ui/proc-macro/auxiliary/{issue_38586.rs => issue-38586.rs} (100%) rename src/test/ui/proc-macro/auxiliary/{issue_50493.rs => issue-50493.rs} (100%) rename src/test/ui/resolve/auxiliary/{issue_19452_aux.rs => issue-19452-aux.rs} (100%) rename src/test/ui/resolve/auxiliary/{issue_3907.rs => issue-3907.rs} (100%) rename src/test/ui/{auxiliary/use_from_trait_xc.rs => use/auxiliary/use-from-trait-xc.rs} (100%) delete mode 100644 src/test/ui/use/auxiliary/use_from_trait_xc.rs rename src/test/ui/{ => use}/issue-18986.rs (85%) rename src/test/ui/{ => use}/issue-18986.stderr (100%) rename src/test/ui/{useless_comment.rs => useless-comment.rs} (100%) rename src/test/ui/{useless_comment.stderr => useless-comment.stderr} (85%) diff --git a/src/test/debuginfo/auxiliary/issue13213aux.rs b/src/test/debuginfo/auxiliary/issue-13213-aux.rs similarity index 100% rename from src/test/debuginfo/auxiliary/issue13213aux.rs rename to src/test/debuginfo/auxiliary/issue-13213-aux.rs diff --git a/src/test/debuginfo/issue-13213.rs b/src/test/debuginfo/issue-13213.rs index 898ebe547b360..3c9a365fd4f7b 100644 --- a/src/test/debuginfo/issue-13213.rs +++ b/src/test/debuginfo/issue-13213.rs @@ -1,8 +1,8 @@ // min-lldb-version: 310 -// aux-build:issue13213aux.rs +// aux-build:issue-13213-aux.rs -extern crate issue13213aux; +extern crate issue_13213_aux; // compile-flags:-g @@ -10,6 +10,6 @@ extern crate issue13213aux; // statics that are marked with AvailableExternallyLinkage in the importing crate, may actually not // be available because they have been optimized out from the exporting crate. fn main() { - let b: issue13213aux::S = issue13213aux::A; + let b: issue_13213_aux::S = issue_13213_aux::A; println!("Nothing to do here..."); } diff --git a/src/test/incremental/auxiliary/issue_49482_macro_def.rs b/src/test/incremental/auxiliary/issue-49482-macro-def.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_49482_macro_def.rs rename to src/test/incremental/auxiliary/issue-49482-macro-def.rs diff --git a/src/test/incremental/auxiliary/issue_49482_reexport.rs b/src/test/incremental/auxiliary/issue-49482-reexport.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_49482_reexport.rs rename to src/test/incremental/auxiliary/issue-49482-reexport.rs diff --git a/src/test/incremental/auxiliary/issue_54059.rs b/src/test/incremental/auxiliary/issue-54059.rs similarity index 100% rename from src/test/incremental/auxiliary/issue_54059.rs rename to src/test/incremental/auxiliary/issue-54059.rs diff --git a/src/test/incremental/issue-49482.rs b/src/test/incremental/issue-49482.rs index 67d2c3876d70f..042ecc0f27954 100644 --- a/src/test/incremental/issue-49482.rs +++ b/src/test/incremental/issue-49482.rs @@ -1,5 +1,5 @@ -// aux-build:issue_49482_macro_def.rs -// aux-build:issue_49482_reexport.rs +// aux-build:issue-49482-macro-def.rs +// aux-build:issue-49482-reexport.rs // revisions: rpass1 extern crate issue_49482_reexport; diff --git a/src/test/incremental/issue-49595/issue_49595.rs b/src/test/incremental/issue-49595/issue-49595.rs similarity index 100% rename from src/test/incremental/issue-49595/issue_49595.rs rename to src/test/incremental/issue-49595/issue-49595.rs diff --git a/src/test/incremental/issue-54059.rs b/src/test/incremental/issue-54059.rs index d78bbccf1bcca..0a5a547509f69 100644 --- a/src/test/incremental/issue-54059.rs +++ b/src/test/incremental/issue-54059.rs @@ -1,4 +1,4 @@ -// aux-build:issue_54059.rs +// aux-build:issue-54059.rs // ignore-wasm32-bare no libc for ffi testing // ignore-windows - dealing with weird symbols issues on dylibs isn't worth it // revisions: rpass1 diff --git a/src/test/pretty/issue_12590_a.rs b/src/test/pretty/issue-12590-a.rs similarity index 75% rename from src/test/pretty/issue_12590_a.rs rename to src/test/pretty/issue-12590-a.rs index 1ddd3c0426371..1a9e85c42d8fb 100644 --- a/src/test/pretty/issue_12590_a.rs +++ b/src/test/pretty/issue-12590-a.rs @@ -2,6 +2,7 @@ // The next line should not be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b; fn main() { } diff --git a/src/test/pretty/issue-12590-b.rs b/src/test/pretty/issue-12590-b.rs new file mode 100644 index 0000000000000..b14c7afa22142 --- /dev/null +++ b/src/test/pretty/issue-12590-b.rs @@ -0,0 +1,5 @@ +// Second part of two-file test + +fn b() { } + +fn main() { } diff --git a/src/test/pretty/issue_12590_c.pp b/src/test/pretty/issue-12590-c.pp similarity index 82% rename from src/test/pretty/issue_12590_c.pp rename to src/test/pretty/issue-12590-c.pp index 2418283530375..1761c0653ce86 100644 --- a/src/test/pretty/issue_12590_c.pp +++ b/src/test/pretty/issue-12590-c.pp @@ -6,10 +6,11 @@ extern crate std; // pretty-compare-only // pretty-mode:expanded -// pp-exact:issue_12590_c.pp +// pp-exact:issue-12590-c.pp // The next line should be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b { fn b() { } diff --git a/src/test/pretty/issue_12590_c.rs b/src/test/pretty/issue-12590-c.rs similarity index 67% rename from src/test/pretty/issue_12590_c.rs rename to src/test/pretty/issue-12590-c.rs index c0da36c2100ef..2cc444edda3d7 100644 --- a/src/test/pretty/issue_12590_c.rs +++ b/src/test/pretty/issue-12590-c.rs @@ -1,9 +1,10 @@ // pretty-compare-only // pretty-mode:expanded -// pp-exact:issue_12590_c.pp +// pp-exact:issue-12590-c.pp // The next line should be expanded +#[path = "issue-12590-b.rs"] mod issue_12590_b; fn main() { } diff --git a/src/test/pretty/issue_12590_b.rs b/src/test/pretty/issue_12590_b.rs deleted file mode 100644 index f188f7bca6983..0000000000000 --- a/src/test/pretty/issue_12590_b.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Second part of two file test -fn b() { } - -fn main() { } diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_partial_eq.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs rename to src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/issue_24106.rs b/src/test/run-pass-fulldeps/auxiliary/issue-24106.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/issue_24106.rs rename to src/test/run-pass-fulldeps/auxiliary/issue-24106.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs rename to src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs rename to src/test/run-pass-fulldeps/auxiliary/llvm-pass-plugin.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs rename to src/test/run-pass-fulldeps/auxiliary/macro-crate-test.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/plugin_args.rs rename to src/test/run-pass-fulldeps/auxiliary/plugin-args.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs rename to src/test/run-pass-fulldeps/auxiliary/roman-numerals.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs b/src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs rename to src/test/run-pass-fulldeps/auxiliary/syntax-extension-with-dll-deps-1.rs diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs index 21b8ec7be9892..ac8fff4f6bfad 100644 --- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs +++ b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_partial_eq.rs +// aux-build:custom-derive-partial-eq.rs // ignore-stage1 #![feature(plugin)] #![plugin(custom_derive_partial_eq)] diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs index 769861e7c94ad..38eaa71dd6aba 100644 --- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs +++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_plugin_attr.rs +// aux-build:custom-derive-plugin-attr.rs // ignore-stage1 #![feature(plugin, rustc_attrs)] diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs index be26943b6dc16..2b0bb51d90aec 100644 --- a/src/test/run-pass-fulldeps/derive-totalsum.rs +++ b/src/test/run-pass-fulldeps/derive-totalsum.rs @@ -1,4 +1,4 @@ -// aux-build:custom_derive_plugin.rs +// aux-build:custom-derive-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs index 50e9b14b26832..2add3ccbe36f2 100644 --- a/src/test/run-pass-fulldeps/issue-15778-pass.rs +++ b/src/test/run-pass-fulldeps/issue-15778-pass.rs @@ -1,4 +1,4 @@ -// aux-build:lint_for_crate.rs +// aux-build:lint-for-crate.rs // ignore-stage1 // compile-flags: -D crate-not-okay diff --git a/src/test/run-pass-fulldeps/issue_24106.rs b/src/test/run-pass-fulldeps/issue-24106.rs similarity index 71% rename from src/test/run-pass-fulldeps/issue_24106.rs rename to src/test/run-pass-fulldeps/issue-24106.rs index a497d9f33ae81..e8e85ff33772e 100644 --- a/src/test/run-pass-fulldeps/issue_24106.rs +++ b/src/test/run-pass-fulldeps/issue-24106.rs @@ -1,4 +1,4 @@ -// aux-build:issue_24106.rs +// aux-build:issue-24106.rs extern crate issue_24106; diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs index cb01eddd7e49e..133f6302bde57 100644 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ b/src/test/run-pass-fulldeps/issue-40663.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -// aux-build:custom_derive_plugin.rs +// aux-build:custom-derive-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs index 3aad40ecfe8aa..411631104a4bc 100644 --- a/src/test/run-pass-fulldeps/llvm-pass-plugin.rs +++ b/src/test/run-pass-fulldeps/llvm-pass-plugin.rs @@ -1,4 +1,4 @@ -// aux-build:llvm_pass_plugin.rs +// aux-build:llvm-pass-plugin.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs index dcac160c4c974..573bfca31683f 100644 --- a/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs +++ b/src/test/run-pass-fulldeps/macro-crate-multi-decorator.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_imports)] -// aux-build:macro_crate_test.rs +// aux-build:macro-crate-test.rs // ignore-stage1 #![feature(rustc_attrs)] diff --git a/src/test/run-pass-fulldeps/plugin-args-1.rs b/src/test/run-pass-fulldeps/plugin-args-1.rs index 0111af1c76804..1bdf004e3052f 100644 --- a/src/test/run-pass-fulldeps/plugin-args-1.rs +++ b/src/test/run-pass-fulldeps/plugin-args-1.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/plugin-args-2.rs b/src/test/run-pass-fulldeps/plugin-args-2.rs index e4a3dfab5668d..83091df058283 100644 --- a/src/test/run-pass-fulldeps/plugin-args-2.rs +++ b/src/test/run-pass-fulldeps/plugin-args-2.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/plugin-args-3.rs b/src/test/run-pass-fulldeps/plugin-args-3.rs index 4696233f2818e..9cd9bee5a0fe9 100644 --- a/src/test/run-pass-fulldeps/plugin-args-3.rs +++ b/src/test/run-pass-fulldeps/plugin-args-3.rs @@ -1,4 +1,4 @@ -// aux-build:plugin_args.rs +// aux-build:plugin-args.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass-fulldeps/roman-numerals-macro.rs b/src/test/run-pass-fulldeps/roman-numerals-macro.rs index 59a2d132cdc26..49c12e426fee2 100644 --- a/src/test/run-pass-fulldeps/roman-numerals-macro.rs +++ b/src/test/run-pass-fulldeps/roman-numerals-macro.rs @@ -1,4 +1,4 @@ -// aux-build:roman_numerals.rs +// aux-build:roman-numerals.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/run-pass/auxiliary/rmeta_rlib.rs b/src/test/run-pass/auxiliary/rmeta-rlib.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta_rlib.rs rename to src/test/run-pass/auxiliary/rmeta-rlib.rs diff --git a/src/test/run-pass/auxiliary/rmeta_rmeta.rs b/src/test/run-pass/auxiliary/rmeta-rmeta.rs similarity index 100% rename from src/test/run-pass/auxiliary/rmeta_rmeta.rs rename to src/test/run-pass/auxiliary/rmeta-rmeta.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_10031_aux.rs b/src/test/run-pass/issues/auxiliary/issue-10031-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_10031_aux.rs rename to src/test/run-pass/issues/auxiliary/issue-10031-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_1.rs b/src/test/run-pass/issues/auxiliary/issue-12612-1.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_12612_1.rs rename to src/test/run-pass/issues/auxiliary/issue-12612-1.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_12612_2.rs b/src/test/run-pass/issues/auxiliary/issue-12612-2.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_12612_2.rs rename to src/test/run-pass/issues/auxiliary/issue-12612-2.rs diff --git a/src/test/run-pass/issues/auxiliary/issue13507.rs b/src/test/run-pass/issues/auxiliary/issue-13507.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue13507.rs rename to src/test/run-pass/issues/auxiliary/issue-13507.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_19293.rs b/src/test/run-pass/issues/auxiliary/issue-19293.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_19293.rs rename to src/test/run-pass/issues/auxiliary/issue-19293.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_20389.rs b/src/test/run-pass/issues/auxiliary/issue-20389.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_20389.rs rename to src/test/run-pass/issues/auxiliary/issue-20389.rs diff --git a/src/test/run-pass/issues/auxiliary/issue2170lib.rs b/src/test/run-pass/issues/auxiliary/issue-2170-lib.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue2170lib.rs rename to src/test/run-pass/issues/auxiliary/issue-2170-lib.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_a.rs b/src/test/run-pass/issues/auxiliary/issue-2316-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2316_a.rs rename to src/test/run-pass/issues/auxiliary/issue-2316-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2316_b.rs b/src/test/run-pass/issues/auxiliary/issue-2316-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2316_b.rs rename to src/test/run-pass/issues/auxiliary/issue-2316-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2472_b.rs b/src/test/run-pass/issues/auxiliary/issue-2472-b.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2472_b.rs rename to src/test/run-pass/issues/auxiliary/issue-2472-b.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_2723_a.rs b/src/test/run-pass/issues/auxiliary/issue-2723-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_2723_a.rs rename to src/test/run-pass/issues/auxiliary/issue-2723-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc similarity index 62% rename from src/test/run-pass/issues/auxiliary/issue_3136_a.rc rename to src/test/run-pass/issues/auxiliary/issue-3136-a.rc index 46da4132b82d7..cd5fd3145055c 100644 --- a/src/test/run-pass/issues/auxiliary/issue_3136_a.rc +++ b/src/test/run-pass/issues/auxiliary/issue-3136-a.rc @@ -1,3 +1,4 @@ #![crate_type = "lib"] +#[path = "issue-3136-a.rs"] pub mod issue_3136_a; diff --git a/src/test/run-pass/issues/auxiliary/issue_3136_a.rs b/src/test/run-pass/issues/auxiliary/issue-3136-a.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_3136_a.rs rename to src/test/run-pass/issues/auxiliary/issue-3136-a.rs diff --git a/src/test/run-pass/issues/auxiliary/issue34796aux.rs b/src/test/run-pass/issues/auxiliary/issue-34796-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue34796aux.rs rename to src/test/run-pass/issues/auxiliary/issue-34796-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38190.rs b/src/test/run-pass/issues/auxiliary/issue-38190.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38190.rs rename to src/test/run-pass/issues/auxiliary/issue-38190.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38226_aux.rs b/src/test/run-pass/issues/auxiliary/issue-38226-aux.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38226_aux.rs rename to src/test/run-pass/issues/auxiliary/issue-38226-aux.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38715-modern.rs b/src/test/run-pass/issues/auxiliary/issue-38715-modern.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38715-modern.rs rename to src/test/run-pass/issues/auxiliary/issue-38715-modern.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_38715.rs b/src/test/run-pass/issues/auxiliary/issue-38715.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_38715.rs rename to src/test/run-pass/issues/auxiliary/issue-38715.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_3979_traits.rs b/src/test/run-pass/issues/auxiliary/issue-3979-traits.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_3979_traits.rs rename to src/test/run-pass/issues/auxiliary/issue-3979-traits.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_39823.rs b/src/test/run-pass/issues/auxiliary/issue-39823.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_39823.rs rename to src/test/run-pass/issues/auxiliary/issue-39823.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_40469.rs b/src/test/run-pass/issues/auxiliary/issue-40469.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_40469.rs rename to src/test/run-pass/issues/auxiliary/issue-40469.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_41053.rs b/src/test/run-pass/issues/auxiliary/issue-41053.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_41053.rs rename to src/test/run-pass/issues/auxiliary/issue-41053.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_42007_s.rs b/src/test/run-pass/issues/auxiliary/issue-42007-s.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_42007_s.rs rename to src/test/run-pass/issues/auxiliary/issue-42007-s.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_8401.rs b/src/test/run-pass/issues/auxiliary/issue-8401.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_8401.rs rename to src/test/run-pass/issues/auxiliary/issue-8401.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9123.rs b/src/test/run-pass/issues/auxiliary/issue-9123.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9123.rs rename to src/test/run-pass/issues/auxiliary/issue-9123.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9155.rs b/src/test/run-pass/issues/auxiliary/issue-9155.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9155.rs rename to src/test/run-pass/issues/auxiliary/issue-9155.rs diff --git a/src/test/run-pass/issues/auxiliary/issue_9188.rs b/src/test/run-pass/issues/auxiliary/issue-9188.rs similarity index 100% rename from src/test/run-pass/issues/auxiliary/issue_9188.rs rename to src/test/run-pass/issues/auxiliary/issue-9188.rs diff --git a/src/test/run-pass/issues/issue-10031.rs b/src/test/run-pass/issues/issue-10031.rs index ba1fbac48453a..136df05c2397a 100644 --- a/src/test/run-pass/issues/issue-10031.rs +++ b/src/test/run-pass/issues/issue-10031.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_10031_aux.rs +// aux-build:issue-10031-aux.rs // pretty-expanded FIXME #23616 extern crate issue_10031_aux; diff --git a/src/test/run-pass/issues/issue-12612.rs b/src/test/run-pass/issues/issue-12612.rs index 158c2aed13724..d254f6941a339 100644 --- a/src/test/run-pass/issues/issue-12612.rs +++ b/src/test/run-pass/issues/issue-12612.rs @@ -1,7 +1,7 @@ // run-pass #![allow(unused_imports)] -// aux-build:issue_12612_1.rs -// aux-build:issue_12612_2.rs +// aux-build:issue-12612-1.rs +// aux-build:issue-12612-2.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-13507-2.rs b/src/test/run-pass/issues/issue-13507-2.rs index 4ea95149dc6b5..ce920a3ccab9d 100644 --- a/src/test/run-pass/issues/issue-13507-2.rs +++ b/src/test/run-pass/issues/issue-13507-2.rs @@ -1,14 +1,14 @@ // run-pass #![allow(unused_imports)] -// aux-build:issue13507.rs +// aux-build:issue-13507.rs -extern crate issue13507; -use issue13507::testtypes; +extern crate issue_13507; +use issue_13507::testtypes; use std::any::TypeId; pub fn type_ids() -> Vec { - use issue13507::testtypes::*; + use issue_13507::testtypes::*; vec![ TypeId::of::(), TypeId::of::(), @@ -30,7 +30,7 @@ pub fn type_ids() -> Vec { } pub fn main() { - let othercrate = issue13507::testtypes::type_ids(); + let othercrate = issue_13507::testtypes::type_ids(); let thiscrate = type_ids(); assert_eq!(thiscrate, othercrate); } diff --git a/src/test/run-pass/issue-18952.rs b/src/test/run-pass/issues/issue-18952.rs similarity index 100% rename from src/test/run-pass/issue-18952.rs rename to src/test/run-pass/issues/issue-18952.rs diff --git a/src/test/run-pass/issues/issue-19293.rs b/src/test/run-pass/issues/issue-19293.rs index 90f96566f382b..b6e9e3d065a48 100644 --- a/src/test/run-pass/issues/issue-19293.rs +++ b/src/test/run-pass/issues/issue-19293.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_19293.rs +// aux-build:issue-19293.rs // pretty-expanded FIXME #23616 extern crate issue_19293; diff --git a/src/test/run-pass/issues/issue-20389.rs b/src/test/run-pass/issues/issue-20389.rs index 9c5a1844e293b..9bc3efcc1c4bf 100644 --- a/src/test/run-pass/issues/issue-20389.rs +++ b/src/test/run-pass/issues/issue-20389.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_20389.rs +// aux-build:issue-20389.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-2170-exe.rs b/src/test/run-pass/issues/issue-2170-exe.rs new file mode 100644 index 0000000000000..a89579706c8dc --- /dev/null +++ b/src/test/run-pass/issues/issue-2170-exe.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-2170-lib.rs +// pretty-expanded FIXME #23616 + +extern crate issue_2170_lib; + +pub fn main() { + // let _ = issue_2170_lib::rsrc(2); +} diff --git a/src/test/run-pass/issues/issue-2316-c.rs b/src/test/run-pass/issues/issue-2316-c.rs index 6783f3fcfc691..d975aa695c836 100644 --- a/src/test/run-pass/issues/issue-2316-c.rs +++ b/src/test/run-pass/issues/issue-2316-c.rs @@ -1,6 +1,6 @@ // run-pass -// aux-build:issue_2316_a.rs -// aux-build:issue_2316_b.rs +// aux-build:issue-2316-a.rs +// aux-build:issue-2316-b.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs similarity index 62% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs index 3ae53baa82a5a..2275a8da696dd 100644 --- a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs +++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs @@ -4,7 +4,8 @@ // that separate file has many multi-byte characters, to try to // encourage the compiler to trip on them. -mod issue24687_mbcs_in_comments; +#[path = "issue-24687-mbcs-in-comments.rs"] +mod issue_24687_mbcs_in_comments; -pub use issue24687_mbcs_in_comments::D; +pub use issue_24687_mbcs_in_comments::D; diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs similarity index 100% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs diff --git a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs similarity index 62% rename from src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs rename to src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs index a0cda4fad26f5..773792c7a3f1f 100644 --- a/src/test/run-pass/issues/issue24687-embed-debuginfo/main.rs +++ b/src/test/run-pass/issues/issue-24687-embed-debuginfo/main.rs @@ -1,11 +1,11 @@ // run-pass -// aux-build:issue24687_lib.rs +// aux-build:issue-24687-lib.rs // compile-flags:-g -extern crate issue24687_lib as d; +extern crate issue_24687_lib as d; fn main() { - // Create a d, which has a destructor whose body will be codegen'ed + // Create a `D`, which has a destructor whose body will be codegen'ed // into the generated code here, and thus the local debuginfo will // need references into the original source locations from // `importer` above. diff --git a/src/test/run-pass/issues/issue-2472.rs b/src/test/run-pass/issues/issue-2472.rs index cadd0151b4e81..c790bc2d09548 100644 --- a/src/test/run-pass/issues/issue-2472.rs +++ b/src/test/run-pass/issues/issue-2472.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_2472_b.rs +// aux-build:issue-2472-b.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-26873-multifile.rs b/src/test/run-pass/issues/issue-26873-multifile.rs index 7b19713fcc661..da2acf6c9f704 100644 --- a/src/test/run-pass/issues/issue-26873-multifile.rs +++ b/src/test/run-pass/issues/issue-26873-multifile.rs @@ -5,6 +5,7 @@ // ignore-pretty issue #37195 -mod issue_26873_multifile; +#[path = "issue-26873-multifile/mod.rs"] +mod multifile; fn main() {} diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/B.rs b/src/test/run-pass/issues/issue-26873-multifile/A/B.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/B.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/B.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/C.rs b/src/test/run-pass/issues/issue-26873-multifile/A/C.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/C.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/C.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/A/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/A/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/A/mod.rs rename to src/test/run-pass/issues/issue-26873-multifile/A/mod.rs diff --git a/src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir b/src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/compiletest-ignore-dir rename to src/test/run-pass/issues/issue-26873-multifile/compiletest-ignore-dir diff --git a/src/test/run-pass/issues/issue_26873_multifile/mod.rs b/src/test/run-pass/issues/issue-26873-multifile/mod.rs similarity index 100% rename from src/test/run-pass/issues/issue_26873_multifile/mod.rs rename to src/test/run-pass/issues/issue-26873-multifile/mod.rs diff --git a/src/test/run-pass/issues/issue-2723-b.rs b/src/test/run-pass/issues/issue-2723-b.rs index 41f264b6dc075..1910561d0ba43 100644 --- a/src/test/run-pass/issues/issue-2723-b.rs +++ b/src/test/run-pass/issues/issue-2723-b.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_2723_a.rs +// aux-build:issue-2723-a.rs extern crate issue_2723_a; use issue_2723_a::f; diff --git a/src/test/run-pass/issues/issue28498-must-work-ex1.rs b/src/test/run-pass/issues/issue-28498-must-work-ex1.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-must-work-ex1.rs rename to src/test/run-pass/issues/issue-28498-must-work-ex1.rs diff --git a/src/test/run-pass/issues/issue28498-must-work-ex2.rs b/src/test/run-pass/issues/issue-28498-must-work-ex2.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-must-work-ex2.rs rename to src/test/run-pass/issues/issue-28498-must-work-ex2.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-ex1.rs b/src/test/run-pass/issues/issue-28498-ugeh-ex1.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-ex1.rs rename to src/test/run-pass/issues/issue-28498-ugeh-ex1.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-lifetime-param.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-lifetime-param.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-passed-to-fn.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-passed-to-fn.rs diff --git a/src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs b/src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs similarity index 100% rename from src/test/run-pass/issues/issue28498-ugeh-with-trait-bound.rs rename to src/test/run-pass/issues/issue-28498-ugeh-with-trait-bound.rs diff --git a/src/test/run-pass/issues/issue29927-1.rs b/src/test/run-pass/issues/issue-29927-1.rs similarity index 100% rename from src/test/run-pass/issues/issue29927-1.rs rename to src/test/run-pass/issues/issue-29927-1.rs diff --git a/src/test/run-pass/issues/issue_3136_b.rs b/src/test/run-pass/issues/issue-3136-b.rs similarity index 75% rename from src/test/run-pass/issues/issue_3136_b.rs rename to src/test/run-pass/issues/issue-3136-b.rs index f0bdd2b5ec050..c4ca7236e7615 100644 --- a/src/test/run-pass/issues/issue_3136_b.rs +++ b/src/test/run-pass/issues/issue-3136-b.rs @@ -1,7 +1,8 @@ // run-pass -// aux-build:issue_3136_a.rc +// aux-build:issue-3136-a.rc // pretty-expanded FIXME #23616 extern crate issue_3136_a; + pub fn main() {} diff --git a/src/test/run-pass/issues/issue-34796.rs b/src/test/run-pass/issues/issue-34796.rs index a81040b8f4db3..88d5c50a27d29 100644 --- a/src/test/run-pass/issues/issue-34796.rs +++ b/src/test/run-pass/issues/issue-34796.rs @@ -8,8 +8,8 @@ // the symbol name. // The fix was to make the order in which predicates get encoded stable. -// aux-build:issue34796aux.rs -extern crate issue34796aux; +// aux-build:issue-34796-aux.rs +extern crate issue_34796_aux; fn mk() -> T { loop {} } @@ -19,7 +19,7 @@ struct Data { } fn main() { - issue34796aux::bar(|()| { + issue_34796_aux::bar(|()| { Data::<(), std::io::Error> { data: mk(), error: mk(), diff --git a/src/test/run-pass/issues/issue-38190.rs b/src/test/run-pass/issues/issue-38190.rs index 4f83dd263830e..cfa0420c80d1d 100644 --- a/src/test/run-pass/issues/issue-38190.rs +++ b/src/test/run-pass/issues/issue-38190.rs @@ -1,12 +1,15 @@ // run-pass -// aux-build:issue_38190.rs +// aux-build:issue-38190.rs // ignore-pretty issue #37195 #[macro_use] extern crate issue_38190; mod auxiliary { - m!([mod issue_38190;]); + m!([ + #[path = "issue-38190.rs"] + mod issue_38190; + ]); } fn main() {} diff --git a/src/test/run-pass/issues/issue-38226.rs b/src/test/run-pass/issues/issue-38226.rs index cd569c583f3a7..3213e3618a88b 100644 --- a/src/test/run-pass/issues/issue-38226.rs +++ b/src/test/run-pass/issues/issue-38226.rs @@ -2,7 +2,7 @@ // This test makes sure that we don't run into a linker error because of the // middle::reachable pass missing trait methods with default impls. -// aux-build:issue_38226_aux.rs +// aux-build:issue-38226-aux.rs // Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty // code gets optimized out: diff --git a/src/test/run-pass/issues/issue-38715.rs b/src/test/run-pass/issues/issue-38715.rs index 9d793147e2475..e3c3a027f3cd0 100644 --- a/src/test/run-pass/issues/issue-38715.rs +++ b/src/test/run-pass/issues/issue-38715.rs @@ -1,6 +1,6 @@ // run-pass -// aux-build:issue_38715.rs -// aux-build:issue_38715-modern.rs +// aux-build:issue-38715.rs +// aux-build:issue-38715-modern.rs // Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!` diff --git a/src/test/run-pass/issues/issue-3979-xcrate.rs b/src/test/run-pass/issues/issue-3979-xcrate.rs index 0e47dee5b65be..fcb1f55c32f9c 100644 --- a/src/test/run-pass/issues/issue-3979-xcrate.rs +++ b/src/test/run-pass/issues/issue-3979-xcrate.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_3979_traits.rs +// aux-build:issue-3979-traits.rs extern crate issue_3979_traits; use issue_3979_traits::{Positioned, Movable}; diff --git a/src/test/run-pass/issues/issue-39823.rs b/src/test/run-pass/issues/issue-39823.rs index 8a52399273b9f..0dfa8a75c4f00 100644 --- a/src/test/run-pass/issues/issue-39823.rs +++ b/src/test/run-pass/issues/issue-39823.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_39823.rs +// aux-build:issue-39823.rs extern crate issue_39823; use issue_39823::{RemoteC, RemoteG}; diff --git a/src/test/run-pass/issues/issue-40469.rs b/src/test/run-pass/issues/issue-40469.rs index 2e8247e032b02..25e08ef85e967 100644 --- a/src/test/run-pass/issues/issue-40469.rs +++ b/src/test/run-pass/issues/issue-40469.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] -include!("auxiliary/issue_40469.rs"); +include!("auxiliary/issue-40469.rs"); fn f() { m!(); } fn main() {} diff --git a/src/test/run-pass/issues/issue-41053.rs b/src/test/run-pass/issues/issue-41053.rs index b9d8f00ff21d6..cd7a0a22623a8 100644 --- a/src/test/run-pass/issues/issue-41053.rs +++ b/src/test/run-pass/issues/issue-41053.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_41053.rs +// aux-build:issue-41053.rs pub trait Trait { fn foo(&self) {} } diff --git a/src/test/run-pass/issues/issue-42007.rs b/src/test/run-pass/issues/issue-42007.rs index de1367ec80f17..a477e476eb9f6 100644 --- a/src/test/run-pass/issues/issue-42007.rs +++ b/src/test/run-pass/issues/issue-42007.rs @@ -1,6 +1,6 @@ // run-pass #![allow(dead_code)] -// aux-build:issue_42007_s.rs +// aux-build:issue-42007-s.rs extern crate issue_42007_s; diff --git a/src/test/run-pass/issue-45510.rs b/src/test/run-pass/issues/issue-45510.rs similarity index 100% rename from src/test/run-pass/issue-45510.rs rename to src/test/run-pass/issues/issue-45510.rs diff --git a/src/test/run-pass/issue-48006.rs b/src/test/run-pass/issues/issue-48006.rs similarity index 100% rename from src/test/run-pass/issue-48006.rs rename to src/test/run-pass/issues/issue-48006.rs diff --git a/src/test/run-pass/issue-53728.rs b/src/test/run-pass/issues/issue-53728.rs similarity index 100% rename from src/test/run-pass/issue-53728.rs rename to src/test/run-pass/issues/issue-53728.rs diff --git a/src/test/run-pass/issue-53843.rs b/src/test/run-pass/issues/issue-53843.rs similarity index 100% rename from src/test/run-pass/issue-53843.rs rename to src/test/run-pass/issues/issue-53843.rs diff --git a/src/test/run-pass/issue-54462-mutable-noalias-correctness.rs b/src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs similarity index 100% rename from src/test/run-pass/issue-54462-mutable-noalias-correctness.rs rename to src/test/run-pass/issues/issue-54462-mutable-noalias-correctness.rs diff --git a/src/test/run-pass/issue-54467.rs b/src/test/run-pass/issues/issue-54467.rs similarity index 100% rename from src/test/run-pass/issue-54467.rs rename to src/test/run-pass/issues/issue-54467.rs diff --git a/src/test/run-pass/issue-55376.rs b/src/test/run-pass/issues/issue-55376.rs similarity index 100% rename from src/test/run-pass/issue-55376.rs rename to src/test/run-pass/issues/issue-55376.rs diff --git a/src/test/run-pass/issue-55380.rs b/src/test/run-pass/issues/issue-55380.rs similarity index 100% rename from src/test/run-pass/issue-55380.rs rename to src/test/run-pass/issues/issue-55380.rs diff --git a/src/test/run-pass/issue-56237.rs b/src/test/run-pass/issues/issue-56237.rs similarity index 100% rename from src/test/run-pass/issue-56237.rs rename to src/test/run-pass/issues/issue-56237.rs diff --git a/src/test/run-pass/issues/issue-8401.rs b/src/test/run-pass/issues/issue-8401.rs index 97d66c5e40f04..1257bab6c0cd6 100644 --- a/src/test/run-pass/issues/issue-8401.rs +++ b/src/test/run-pass/issues/issue-8401.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_8401.rs +// aux-build:issue-8401.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9123.rs b/src/test/run-pass/issues/issue-9123.rs index 5072ca6ba5374..8c21d06c4776f 100644 --- a/src/test/run-pass/issues/issue-9123.rs +++ b/src/test/run-pass/issues/issue-9123.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9123.rs +// aux-build:issue-9123.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue_9155.rs b/src/test/run-pass/issues/issue-9155.rs similarity index 83% rename from src/test/run-pass/issues/issue_9155.rs rename to src/test/run-pass/issues/issue-9155.rs index 87c453be1420b..4b5c451e853ed 100644 --- a/src/test/run-pass/issues/issue_9155.rs +++ b/src/test/run-pass/issues/issue-9155.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9155.rs +// aux-build:issue-9155.rs // pretty-expanded FIXME #23616 diff --git a/src/test/run-pass/issues/issue-9188.rs b/src/test/run-pass/issues/issue-9188.rs index d7c39e9d50556..34e61fdf68bc0 100644 --- a/src/test/run-pass/issues/issue-9188.rs +++ b/src/test/run-pass/issues/issue-9188.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue_9188.rs +// aux-build:issue-9188.rs extern crate issue_9188; diff --git a/src/test/run-pass/issues/issue2170exe.rs b/src/test/run-pass/issues/issue2170exe.rs deleted file mode 100644 index 4169ddf9bb7f7..0000000000000 --- a/src/test/run-pass/issues/issue2170exe.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass -// aux-build:issue2170lib.rs -// pretty-expanded FIXME #23616 - -extern crate issue2170lib; - -pub fn main() { - // let _ = issue2170lib::rsrc(2); -} diff --git a/src/test/run-pass/rmeta.rs b/src/test/run-pass/rmeta.rs index bd8125bbb5648..cbbdd78dc204b 100644 --- a/src/test/run-pass/rmeta.rs +++ b/src/test/run-pass/rmeta.rs @@ -1,8 +1,8 @@ // Test that using rlibs and rmeta dep crates work together. Specifically, that // there can be both an rmeta and an rlib file and rustc will prefer the rlib. -// aux-build:rmeta_rmeta.rs -// aux-build:rmeta_rlib.rs +// aux-build:rmeta-rmeta.rs +// aux-build:rmeta-rlib.rs extern crate rmeta_aux; use rmeta_aux::Foo; diff --git a/src/test/rustdoc/auxiliary/enum_primitive.rs b/src/test/rustdoc/auxiliary/enum-primitive.rs similarity index 100% rename from src/test/rustdoc/auxiliary/enum_primitive.rs rename to src/test/rustdoc/auxiliary/enum-primitive.rs diff --git a/src/test/rustdoc/auxiliary/reexp_stripped.rs b/src/test/rustdoc/auxiliary/reexp-stripped.rs similarity index 100% rename from src/test/rustdoc/auxiliary/reexp_stripped.rs rename to src/test/rustdoc/auxiliary/reexp-stripped.rs diff --git a/src/test/rustdoc/no-stack-overflow-25295.rs b/src/test/rustdoc/no-stack-overflow-25295.rs index 7e5c0279031b9..dd79f1e4baaa0 100644 --- a/src/test/rustdoc/no-stack-overflow-25295.rs +++ b/src/test/rustdoc/no-stack-overflow-25295.rs @@ -1,5 +1,5 @@ -// ensure this code doesn't stack overflow -// aux-build:enum_primitive.rs +// Ensure this code doesn't stack overflow. +// aux-build:enum-primitive.rs #[macro_use] extern crate enum_primitive; @@ -33,4 +33,3 @@ enum_from_primitive! { Z1,Z2,Z3,Z4,Z5,Z6, } } - diff --git a/src/test/rustdoc/redirect.rs b/src/test/rustdoc/redirect.rs index 65c57ab65bee9..e3a14c7a74a00 100644 --- a/src/test/rustdoc/redirect.rs +++ b/src/test/rustdoc/redirect.rs @@ -1,4 +1,4 @@ -// aux-build:reexp_stripped.rs +// aux-build:reexp-stripped.rs // build-aux-docs // ignore-cross-compile diff --git a/src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/attr_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_for_crate.rs rename to src/test/ui-fulldeps/auxiliary/lint-for-crate.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/lint_tool_test.rs rename to src/test/ui-fulldeps/auxiliary/lint-tool-test.rs diff --git a/src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs b/src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/rlib_crate_test.rs rename to src/test/ui-fulldeps/auxiliary/rlib-crate-test.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs similarity index 100% rename from src/test/ui-fulldeps/dropck_tarena_cycle_checked.rs rename to src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr similarity index 88% rename from src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr rename to src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr index 37d8b964c2428..b6d5ee0cafef6 100644 --- a/src/test/ui-fulldeps/dropck_tarena_cycle_checked.stderr +++ b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.stderr @@ -1,5 +1,5 @@ error[E0597]: `arena` does not live long enough - --> $DIR/dropck_tarena_cycle_checked.rs:116:8 + --> $DIR/dropck-tarena-cycle-checked.rs:116:8 | LL | f(&arena); | ^^^^^ borrowed value does not live long enough diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs similarity index 100% rename from src/test/ui-fulldeps/dropck_tarena_unsound_drop.rs rename to src/test/ui-fulldeps/dropck-tarena-unsound-drop.rs diff --git a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr similarity index 89% rename from src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr rename to src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr index c791b8b451e50..1e612f049837d 100644 --- a/src/test/ui-fulldeps/dropck_tarena_unsound_drop.stderr +++ b/src/test/ui-fulldeps/dropck-tarena-unsound-drop.stderr @@ -1,5 +1,5 @@ error[E0597]: `arena` does not live long enough - --> $DIR/dropck_tarena_unsound_drop.rs:41:8 + --> $DIR/dropck-tarena-unsound-drop.rs:41:8 | LL | f(&arena); | ^^^^^ borrowed value does not live long enough diff --git a/src/test/ui-fulldeps/gated-plugin.rs b/src/test/ui-fulldeps/gated-plugin.rs index a647585e621fe..be1ec0614803b 100644 --- a/src/test/ui-fulldeps/gated-plugin.rs +++ b/src/test/ui-fulldeps/gated-plugin.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs #![plugin(attr_plugin_test)] //~^ ERROR compiler plugins are experimental and possibly buggy diff --git a/src/test/ui-fulldeps/issue-15778-fail.rs b/src/test/ui-fulldeps/issue-15778-fail.rs index 91c379673b3da..75c52fdb4bd28 100644 --- a/src/test/ui-fulldeps/issue-15778-fail.rs +++ b/src/test/ui-fulldeps/issue-15778-fail.rs @@ -1,4 +1,4 @@ -// aux-build:lint_for_crate.rs +// aux-build:lint-for-crate.rs // ignore-stage1 // compile-flags: -D crate-not-okay diff --git a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs index 75e0a8fc31f7c..c9d8654a90974 100644 --- a/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs +++ b/src/test/ui-fulldeps/lint-group-plugin-deny-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_group_plugin_test.rs +// aux-build:lint-group-plugin-test.rs // ignore-stage1 // compile-flags: -D lint-me diff --git a/src/test/ui-fulldeps/lint-group-plugin.rs b/src/test/ui-fulldeps/lint-group-plugin.rs index 7a650afe5f8fa..55a880be0f985 100644 --- a/src/test/ui-fulldeps/lint-group-plugin.rs +++ b/src/test/ui-fulldeps/lint-group-plugin.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_group_plugin_test.rs +// aux-build:lint-group-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs index 21042c5e7d084..8017379ab3d44 100644 --- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -A test-lint diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs index 0dca00040bfe6..fd681536b5b2b 100644 --- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -Z extra-plugins=lint_plugin_test diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs index 65a3623618020..2d424af870707 100644 --- a/src/test/ui-fulldeps/lint-plugin-deny-attr.rs +++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs index b0c4dc0bce516..87324e85b3be7 100644 --- a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -D test-lint diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs index 964fed3b37d11..c7f7f2be99ed5 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs index 07bd785ee7137..91fe3b65be6fc 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs @@ -1,4 +1,4 @@ -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 // compile-flags: -F test-lint diff --git a/src/test/ui-fulldeps/lint-plugin.rs b/src/test/ui-fulldeps/lint-plugin.rs index 031f3b86b1438..5f8bc16301a74 100644 --- a/src/test/ui-fulldeps/lint-plugin.rs +++ b/src/test/ui-fulldeps/lint-plugin.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_plugin_test.rs +// aux-build:lint-plugin-test.rs // ignore-stage1 #![feature(plugin)] #![plugin(lint_plugin_test)] diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs similarity index 66% rename from src/test/ui-fulldeps/lint_tool_cmdline_allow.rs rename to src/test/ui-fulldeps/lint-tool-cmdline-allow.rs index d60f41dd5a327..529f04c6fc4dd 100644 --- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.rs +++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:lint_tool_test.rs +// aux-build:lint-tool-test.rs // ignore-stage1 // compile-flags: -A test-lint @@ -7,7 +7,6 @@ #![warn(unused)] #![plugin(lint_tool_test)] -fn lintme() { } +fn lintme() {} -pub fn main() { -} +pub fn main() {} diff --git a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr similarity index 71% rename from src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr rename to src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr index 9634f1d572fca..1d85101383136 100644 --- a/src/test/ui-fulldeps/lint_tool_cmdline_allow.stderr +++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr @@ -3,21 +3,21 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore = note: requested on the command line with `-A test_lint` warning: item is named 'lintme' - --> $DIR/lint_tool_cmdline_allow.rs:10:1 + --> $DIR/lint-tool-cmdline-allow.rs:10:1 | -LL | fn lintme() { } - | ^^^^^^^^^^^^^^^ +LL | fn lintme() {} + | ^^^^^^^^^^^^^^ | = note: #[warn(clippy::test_lint)] on by default warning: function is never used: `lintme` - --> $DIR/lint_tool_cmdline_allow.rs:10:1 + --> $DIR/lint-tool-cmdline-allow.rs:10:1 | -LL | fn lintme() { } +LL | fn lintme() {} | ^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_cmdline_allow.rs:7:9 + --> $DIR/lint-tool-cmdline-allow.rs:7:9 | LL | #![warn(unused)] | ^^^^^^ diff --git a/src/test/ui-fulldeps/lint_tool_test.rs b/src/test/ui-fulldeps/lint-tool-test.rs similarity index 96% rename from src/test/ui-fulldeps/lint_tool_test.rs rename to src/test/ui-fulldeps/lint-tool-test.rs index 04608b62f43c1..8bd06d1f1e34f 100644 --- a/src/test/ui-fulldeps/lint_tool_test.rs +++ b/src/test/ui-fulldeps/lint-tool-test.rs @@ -1,4 +1,4 @@ -// aux-build:lint_tool_test.rs +// aux-build:lint-tool-test.rs // ignore-stage1 // compile-flags: --cfg foo diff --git a/src/test/ui-fulldeps/lint_tool_test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr similarity index 85% rename from src/test/ui-fulldeps/lint_tool_test.stderr rename to src/test/ui-fulldeps/lint-tool-test.stderr index cec8800a25c7f..67e55e65c7e77 100644 --- a/src/test/ui-fulldeps/lint_tool_test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr @@ -1,5 +1,5 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:8:23 + --> $DIR/lint-tool-test.rs:8:23 | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` @@ -7,19 +7,19 @@ LL | #![cfg_attr(foo, warn(test_lint))] = note: #[warn(renamed_and_removed_lints)] on by default warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:25:9 + --> $DIR/lint-tool-test.rs:25:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` warning: unknown lint: `this_lint_does_not_exist` - --> $DIR/lint_tool_test.rs:27:8 + --> $DIR/lint-tool-test.rs:27:8 | LL | #[deny(this_lint_does_not_exist)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,32 +27,32 @@ LL | #[deny(this_lint_does_not_exist)] = note: #[warn(unknown_lints)] on by default warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint_tool_test.rs:8:23 + --> $DIR/lint-tool-test.rs:8:23 | LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` error: item is named 'lintme' - --> $DIR/lint_tool_test.rs:14:1 + --> $DIR/lint-tool-test.rs:14:1 | LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: #[deny(clippy::test_lint)] implied by #[deny(clippy::group)] error: item is named 'lintmetoo' - --> $DIR/lint_tool_test.rs:22:5 + --> $DIR/lint-tool-test.rs:22:5 | LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint_tool_test.rs:11:9 + --> $DIR/lint-tool-test.rs:11:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ diff --git a/src/test/ui-fulldeps/macro-crate-rlib.rs b/src/test/ui-fulldeps/macro-crate-rlib.rs index 21e62171f0f0d..2962bb51fc418 100644 --- a/src/test/ui-fulldeps/macro-crate-rlib.rs +++ b/src/test/ui-fulldeps/macro-crate-rlib.rs @@ -1,4 +1,4 @@ -// aux-build:rlib_crate_test.rs +// aux-build:rlib-crate-test.rs // ignore-tidy-linelength // ignore-cross-compile gives a different error message diff --git a/src/test/ui-fulldeps/plugin-as-extern-crate.rs b/src/test/ui-fulldeps/plugin-as-extern-crate.rs index 37ac8dfa39101..c671ab581efbe 100644 --- a/src/test/ui-fulldeps/plugin-as-extern-crate.rs +++ b/src/test/ui-fulldeps/plugin-as-extern-crate.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs // ignore-cross-compile // // attr_plugin_test will not compile on a cross-compiled target because diff --git a/src/test/ui-fulldeps/plugin-attr-register-deny.rs b/src/test/ui-fulldeps/plugin-attr-register-deny.rs index f9922f7f6060e..8be73e330abf7 100644 --- a/src/test/ui-fulldeps/plugin-attr-register-deny.rs +++ b/src/test/ui-fulldeps/plugin-attr-register-deny.rs @@ -1,4 +1,4 @@ -// aux-build:attr_plugin_test.rs +// aux-build:attr-plugin-test.rs // ignore-stage1 #![feature(plugin)] diff --git a/src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs b/src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs similarity index 100% rename from src/test/ui/auxiliary/default_ty_param_cross_crate_crate.rs rename to src/test/ui/auxiliary/default-ty-param-cross-crate-crate.rs diff --git a/src/test/ui/auxiliary/define_macro.rs b/src/test/ui/auxiliary/define-macro.rs similarity index 100% rename from src/test/ui/auxiliary/define_macro.rs rename to src/test/ui/auxiliary/define-macro.rs diff --git a/src/test/ui/auxiliary/orphan_check_diagnostics.rs b/src/test/ui/auxiliary/orphan-check-diagnostics.rs similarity index 100% rename from src/test/ui/auxiliary/orphan_check_diagnostics.rs rename to src/test/ui/auxiliary/orphan-check-diagnostics.rs diff --git a/src/test/ui/auxiliary/pub_and_stability.rs b/src/test/ui/auxiliary/pub-and-stability.rs similarity index 100% rename from src/test/ui/auxiliary/pub_and_stability.rs rename to src/test/ui/auxiliary/pub-and-stability.rs diff --git a/src/test/ui/auxiliary/rmeta_meta.rs b/src/test/ui/auxiliary/rmeta-meta.rs similarity index 100% rename from src/test/ui/auxiliary/rmeta_meta.rs rename to src/test/ui/auxiliary/rmeta-meta.rs diff --git a/src/test/ui/auxiliary/rmeta_rlib.rs b/src/test/ui/auxiliary/rmeta-rlib.rs similarity index 100% rename from src/test/ui/auxiliary/rmeta_rlib.rs rename to src/test/ui/auxiliary/rmeta-rlib.rs diff --git a/src/test/ui/auxiliary/stability_cfg2.rs b/src/test/ui/auxiliary/stability-cfg2.rs similarity index 100% rename from src/test/ui/auxiliary/stability_cfg2.rs rename to src/test/ui/auxiliary/stability-cfg2.rs diff --git a/src/test/ui/auxiliary/xc_private_method_lib.rs b/src/test/ui/auxiliary/xc-private-method-lib.rs similarity index 100% rename from src/test/ui/auxiliary/xc_private_method_lib.rs rename to src/test/ui/auxiliary/xc-private-method-lib.rs diff --git a/src/test/ui/e0119/auxiliary/issue_23563_a.rs b/src/test/ui/e0119/auxiliary/issue-23563-a.rs similarity index 100% rename from src/test/ui/e0119/auxiliary/issue_23563_a.rs rename to src/test/ui/e0119/auxiliary/issue-23563-a.rs diff --git a/src/test/ui/e0119/issue-23563.rs b/src/test/ui/e0119/issue-23563.rs index a2804fcf1cc55..f578560c552a8 100644 --- a/src/test/ui/e0119/issue-23563.rs +++ b/src/test/ui/e0119/issue-23563.rs @@ -1,4 +1,4 @@ -// aux-build:issue_23563_a.rs +// aux-build:issue-23563-a.rs // Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672 diff --git a/src/test/ui/enable-unstable-lib-feature.rs b/src/test/ui/enable-unstable-lib-feature.rs index 2f248bf14c151..383c6868ce2fe 100644 --- a/src/test/ui/enable-unstable-lib-feature.rs +++ b/src/test/ui/enable-unstable-lib-feature.rs @@ -1,6 +1,6 @@ // Test that enabling an unstable feature disables warnings -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs #![feature(unstable_test_feature)] #![deny(non_snake_case)] // To trigger a hard error diff --git a/src/test/ui/explore-issue-38412.rs b/src/test/ui/explore-issue-38412.rs index cd0a69b0d8b8e..e7bcd7c6bfe65 100644 --- a/src/test/ui/explore-issue-38412.rs +++ b/src/test/ui/explore-issue-38412.rs @@ -1,4 +1,4 @@ -// aux-build:pub_and_stability.rs +// aux-build:pub-and-stability.rs #![feature(unused_feature)] @@ -63,5 +63,4 @@ fn main() { t.pub_crate(); //~ ERROR `pub_crate` is private t.pub_mod(); //~ ERROR `pub_mod` is private t.private(); //~ ERROR `private` is private - } diff --git a/src/test/ui/issue-42944.rs b/src/test/ui/issues/issue-42944.rs similarity index 100% rename from src/test/ui/issue-42944.rs rename to src/test/ui/issues/issue-42944.rs diff --git a/src/test/ui/issue-42944.stderr b/src/test/ui/issues/issue-42944.stderr similarity index 100% rename from src/test/ui/issue-42944.stderr rename to src/test/ui/issues/issue-42944.stderr diff --git a/src/test/ui/issue-53787-inline-assembler-macro.rs b/src/test/ui/issues/issue-53787-inline-assembler-macro.rs similarity index 100% rename from src/test/ui/issue-53787-inline-assembler-macro.rs rename to src/test/ui/issues/issue-53787-inline-assembler-macro.rs diff --git a/src/test/ui/issue-53787-inline-assembler-macro.stderr b/src/test/ui/issues/issue-53787-inline-assembler-macro.stderr similarity index 100% rename from src/test/ui/issue-53787-inline-assembler-macro.stderr rename to src/test/ui/issues/issue-53787-inline-assembler-macro.stderr diff --git a/src/test/ui/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs similarity index 100% rename from src/test/ui/issue-54943-1.rs rename to src/test/ui/issues/issue-54943-1.rs diff --git a/src/test/ui/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs similarity index 100% rename from src/test/ui/issue-54943-2.rs rename to src/test/ui/issues/issue-54943-2.rs diff --git a/src/test/ui/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs similarity index 100% rename from src/test/ui/issue-54943-3.rs rename to src/test/ui/issues/issue-54943-3.rs diff --git a/src/test/ui/issue-54943.rs b/src/test/ui/issues/issue-54943.rs similarity index 100% rename from src/test/ui/issue-54943.rs rename to src/test/ui/issues/issue-54943.rs diff --git a/src/test/ui/issue-54943.stderr b/src/test/ui/issues/issue-54943.stderr similarity index 100% rename from src/test/ui/issue-54943.stderr rename to src/test/ui/issues/issue-54943.stderr diff --git a/src/test/ui/issue-55511.nll.stderr b/src/test/ui/issues/issue-55511.nll.stderr similarity index 100% rename from src/test/ui/issue-55511.nll.stderr rename to src/test/ui/issues/issue-55511.nll.stderr diff --git a/src/test/ui/issue-55511.rs b/src/test/ui/issues/issue-55511.rs similarity index 100% rename from src/test/ui/issue-55511.rs rename to src/test/ui/issues/issue-55511.rs diff --git a/src/test/ui/issue-55511.stderr b/src/test/ui/issues/issue-55511.stderr similarity index 100% rename from src/test/ui/issue-55511.stderr rename to src/test/ui/issues/issue-55511.stderr diff --git a/src/test/ui/issue-55846.rs b/src/test/ui/issues/issue-55846.rs similarity index 100% rename from src/test/ui/issue-55846.rs rename to src/test/ui/issues/issue-55846.rs diff --git a/src/test/ui/issues/issue_56411_aux.rs b/src/test/ui/issues/issue-56411-aux.rs similarity index 100% rename from src/test/ui/issues/issue_56411_aux.rs rename to src/test/ui/issues/issue-56411-aux.rs diff --git a/src/test/ui/issues/issue-56411.rs b/src/test/ui/issues/issue-56411.rs index 3561c21cc7ee3..163651a7ef607 100644 --- a/src/test/ui/issues/issue-56411.rs +++ b/src/test/ui/issues/issue-56411.rs @@ -1,6 +1,7 @@ macro_rules! import { - ( $($name:ident),* ) => { + ( $(($path:expr, $name:ident)),* ) => { $( + #[path = $path] mod $name; pub use self::$name; //~^ ERROR the name `issue_56411_aux` is defined multiple times @@ -10,7 +11,7 @@ macro_rules! import { } } -import!(issue_56411_aux); +import!(("issue-56411-aux.rs", issue_56411_aux)); fn main() { println!("Hello, world!"); diff --git a/src/test/ui/issues/issue-56411.stderr b/src/test/ui/issues/issue-56411.stderr index dd05852c09159..7b23b3766bed5 100644 --- a/src/test/ui/issues/issue-56411.stderr +++ b/src/test/ui/issues/issue-56411.stderr @@ -1,5 +1,5 @@ error[E0255]: the name `issue_56411_aux` is defined multiple times - --> $DIR/issue-56411.rs:5:21 + --> $DIR/issue-56411.rs:6:21 | LL | mod $name; | ---------- previous definition of the module `issue_56411_aux` here @@ -9,19 +9,19 @@ LL | pub use self::$name; | `issue_56411_aux` reimported here | you can use `as` to change the binding name of the import ... -LL | import!(issue_56411_aux); - | ------------------------- in this macro invocation +LL | import!(("issue-56411-aux.rs", issue_56411_aux)); + | ------------------------------------------------- in this macro invocation | = note: `issue_56411_aux` must be defined only once in the type namespace of this module error[E0365]: `issue_56411_aux` is private, and cannot be re-exported - --> $DIR/issue-56411.rs:5:21 + --> $DIR/issue-56411.rs:6:21 | LL | pub use self::$name; | ^^^^^^^^^^^ re-export of private `issue_56411_aux` ... -LL | import!(issue_56411_aux); - | ------------------------- in this macro invocation +LL | import!(("issue-56411-aux.rs", issue_56411_aux)); + | ------------------------------------------------- in this macro invocation | = note: consider declaring type or module `issue_56411_aux` with `pub` diff --git a/src/test/ui/lint/auxiliary/stability-cfg2.rs b/src/test/ui/lint/auxiliary/stability-cfg2.rs new file mode 100644 index 0000000000000..8a2899584b903 --- /dev/null +++ b/src/test/ui/lint/auxiliary/stability-cfg2.rs @@ -0,0 +1,5 @@ +// compile-flags:--cfg foo + +#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "0"))] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 8f6425bcc77f6..bf574d7144d06 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -2,7 +2,7 @@ // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs // ignore-tidy-linelength #![warn(deprecated)] #![allow(dead_code, unused_extern_crates)] diff --git a/src/test/ui/lint/lint-stability.rs b/src/test/ui/lint/lint-stability.rs index 6ff79083f46ff..3e4a3874d2c4a 100644 --- a/src/test/ui/lint/lint-stability.rs +++ b/src/test/ui/lint/lint-stability.rs @@ -1,7 +1,7 @@ // aux-build:lint_stability.rs // aux-build:inherited_stability.rs // aux-build:stability_cfg1.rs -// aux-build:stability_cfg2.rs +// aux-build:stability-cfg2.rs #![allow(deprecated)] #![allow(dead_code)] diff --git a/src/test/ui/orphan-check-diagnostics.rs b/src/test/ui/orphan-check-diagnostics.rs index 9a29620ae6532..c8803b9ae5d82 100644 --- a/src/test/ui/orphan-check-diagnostics.rs +++ b/src/test/ui/orphan-check-diagnostics.rs @@ -1,5 +1,6 @@ -// aux-build:orphan_check_diagnostics.rs -// see #22388 +// aux-build:orphan-check-diagnostics.rs + +// See issue #22388. extern crate orphan_check_diagnostics; diff --git a/src/test/ui/orphan-check-diagnostics.stderr b/src/test/ui/orphan-check-diagnostics.stderr index 4bd6aa2c154bd..3f868422c7fcb 100644 --- a/src/test/ui/orphan-check-diagnostics.stderr +++ b/src/test/ui/orphan-check-diagnostics.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) - --> $DIR/orphan-check-diagnostics.rs:10:1 + --> $DIR/orphan-check-diagnostics.rs:11:1 | LL | impl RemoteTrait for T where T: LocalTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type diff --git a/src/test/ui/out-of-order-shadowing.rs b/src/test/ui/out-of-order-shadowing.rs index b4cb6a2383013..a0d1a973764ad 100644 --- a/src/test/ui/out-of-order-shadowing.rs +++ b/src/test/ui/out-of-order-shadowing.rs @@ -1,4 +1,4 @@ -// aux-build:define_macro.rs +// aux-build:define-macro.rs macro_rules! bar { () => {} } define_macro!(bar); diff --git a/src/test/ui/proc-macro/auxiliary/issue_38586.rs b/src/test/ui/proc-macro/auxiliary/issue-38586.rs similarity index 100% rename from src/test/ui/proc-macro/auxiliary/issue_38586.rs rename to src/test/ui/proc-macro/auxiliary/issue-38586.rs diff --git a/src/test/ui/proc-macro/auxiliary/issue_50493.rs b/src/test/ui/proc-macro/auxiliary/issue-50493.rs similarity index 100% rename from src/test/ui/proc-macro/auxiliary/issue_50493.rs rename to src/test/ui/proc-macro/auxiliary/issue-50493.rs diff --git a/src/test/ui/proc-macro/issue-38586.rs b/src/test/ui/proc-macro/issue-38586.rs index 4f291ba990ab7..24e88ed93caaf 100644 --- a/src/test/ui/proc-macro/issue-38586.rs +++ b/src/test/ui/proc-macro/issue-38586.rs @@ -1,4 +1,4 @@ -// aux-build:issue_38586.rs +// aux-build:issue-38586.rs #[macro_use] extern crate issue_38586; diff --git a/src/test/ui/proc-macro/issue-50493.rs b/src/test/ui/proc-macro/issue-50493.rs index f504dbdfce247..eeb08f5eebdcc 100644 --- a/src/test/ui/proc-macro/issue-50493.rs +++ b/src/test/ui/proc-macro/issue-50493.rs @@ -1,4 +1,4 @@ -// aux-build:issue_50493.rs +// aux-build:issue-50493.rs #[macro_use] extern crate issue_50493; diff --git a/src/test/ui/resolve/auxiliary/issue_19452_aux.rs b/src/test/ui/resolve/auxiliary/issue-19452-aux.rs similarity index 100% rename from src/test/ui/resolve/auxiliary/issue_19452_aux.rs rename to src/test/ui/resolve/auxiliary/issue-19452-aux.rs diff --git a/src/test/ui/resolve/auxiliary/issue_3907.rs b/src/test/ui/resolve/auxiliary/issue-3907.rs similarity index 100% rename from src/test/ui/resolve/auxiliary/issue_3907.rs rename to src/test/ui/resolve/auxiliary/issue-3907.rs diff --git a/src/test/ui/resolve/issue-19452.rs b/src/test/ui/resolve/issue-19452.rs index 5c58cabb3cdd8..1d3aa49eac67f 100644 --- a/src/test/ui/resolve/issue-19452.rs +++ b/src/test/ui/resolve/issue-19452.rs @@ -1,4 +1,5 @@ -// aux-build:issue_19452_aux.rs +// aux-build:issue-19452-aux.rs + extern crate issue_19452_aux; enum Homura { diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index ef96fffee926b..56a0e397b854c 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -1,11 +1,11 @@ error[E0423]: expected value, found struct variant `Homura::Madoka` - --> $DIR/issue-19452.rs:9:18 + --> $DIR/issue-19452.rs:10:18 | LL | let homura = Homura::Madoka; | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` - --> $DIR/issue-19452.rs:12:18 + --> $DIR/issue-19452.rs:13:18 | LL | let homura = issue_19452_aux::Homura::Madoka; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? diff --git a/src/test/ui/resolve/issue-3907-2.rs b/src/test/ui/resolve/issue-3907-2.rs index 89e10ca4f2c91..dc9624698dfdd 100644 --- a/src/test/ui/resolve/issue-3907-2.rs +++ b/src/test/ui/resolve/issue-3907-2.rs @@ -1,4 +1,5 @@ -// aux-build:issue_3907.rs +// aux-build:issue-3907.rs + extern crate issue_3907; type Foo = issue_3907::Foo+'static; diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 4fce898dfa96c..968c1f3e463d0 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object - --> $DIR/issue-3907-2.rs:10:1 + --> $DIR/issue-3907-2.rs:11:1 | LL | fn bar(_x: Foo) {} | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object diff --git a/src/test/ui/resolve/issue-3907.rs b/src/test/ui/resolve/issue-3907.rs index a76c3134c0ca3..87e465489a481 100644 --- a/src/test/ui/resolve/issue-3907.rs +++ b/src/test/ui/resolve/issue-3907.rs @@ -1,4 +1,5 @@ -// aux-build:issue_3907.rs +// aux-build:issue-3907.rs + extern crate issue_3907; type Foo = issue_3907::Foo; diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 49f7ae844910e..384df571e2a80 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -1,5 +1,5 @@ error[E0404]: expected trait, found type alias `Foo` - --> $DIR/issue-3907.rs:10:6 + --> $DIR/issue-3907.rs:11:6 | LL | impl Foo for S { | ^^^ type aliases cannot be used as traits diff --git a/src/test/ui/rmeta-lib-pass.rs b/src/test/ui/rmeta-lib-pass.rs index 6149b1685f5c7..4ab4117dd6ccd 100644 --- a/src/test/ui/rmeta-lib-pass.rs +++ b/src/test/ui/rmeta-lib-pass.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_rlib.rs +// aux-build:rmeta-rlib.rs // no-prefer-dynamic // compile-pass diff --git a/src/test/ui/rmeta-pass.rs b/src/test/ui/rmeta-pass.rs index bcd40144f7216..9c88de7a0330b 100644 --- a/src/test/ui/rmeta-pass.rs +++ b/src/test/ui/rmeta-pass.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // compile-pass diff --git a/src/test/ui/rmeta_lib.rs b/src/test/ui/rmeta_lib.rs index 345b712e37e47..6c74aec32e30b 100644 --- a/src/test/ui/rmeta_lib.rs +++ b/src/test/ui/rmeta_lib.rs @@ -1,4 +1,4 @@ -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found diff --git a/src/test/ui/rmeta_meta_main.rs b/src/test/ui/rmeta_meta_main.rs index df550775ee465..52cd0c2f53fad 100644 --- a/src/test/ui/rmeta_meta_main.rs +++ b/src/test/ui/rmeta_meta_main.rs @@ -1,5 +1,5 @@ // compile-flags: --emit=metadata -// aux-build:rmeta_meta.rs +// aux-build:rmeta-meta.rs // no-prefer-dynamic // Check that building a metadata crate finds an error with a dependent, diff --git a/src/test/ui/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use-from-trait-xc.rs similarity index 100% rename from src/test/ui/auxiliary/use_from_trait_xc.rs rename to src/test/ui/use/auxiliary/use-from-trait-xc.rs diff --git a/src/test/ui/use/auxiliary/use_from_trait_xc.rs b/src/test/ui/use/auxiliary/use_from_trait_xc.rs deleted file mode 100644 index 4abe11941b11f..0000000000000 --- a/src/test/ui/use/auxiliary/use_from_trait_xc.rs +++ /dev/null @@ -1,29 +0,0 @@ -pub use self::sub::{Bar, Baz}; - -pub trait Trait { - fn foo(&self); - type Assoc; - const CONST: u32; -} - -struct Foo; - -impl Foo { - pub fn new() {} - - pub const C: u32 = 0; -} - -mod sub { - pub struct Bar; - - impl Bar { - pub fn new() {} - } - - pub enum Baz {} - - impl Baz { - pub fn new() {} - } -} diff --git a/src/test/ui/issue-18986.rs b/src/test/ui/use/issue-18986.rs similarity index 85% rename from src/test/ui/issue-18986.rs rename to src/test/ui/use/issue-18986.rs index 1c431a45ab23e..f0b292f2911c0 100644 --- a/src/test/ui/issue-18986.rs +++ b/src/test/ui/use/issue-18986.rs @@ -1,4 +1,4 @@ -// aux-build:use_from_trait_xc.rs +// aux-build:use-from-trait-xc.rs extern crate use_from_trait_xc; pub use use_from_trait_xc::Trait; diff --git a/src/test/ui/issue-18986.stderr b/src/test/ui/use/issue-18986.stderr similarity index 100% rename from src/test/ui/issue-18986.stderr rename to src/test/ui/use/issue-18986.stderr diff --git a/src/test/ui/use/use-from-trait-xc.rs b/src/test/ui/use/use-from-trait-xc.rs index e6f102f6269a7..695ed66a1c183 100644 --- a/src/test/ui/use/use-from-trait-xc.rs +++ b/src/test/ui/use/use-from-trait-xc.rs @@ -1,4 +1,4 @@ -// aux-build:use_from_trait_xc.rs +// aux-build:use-from-trait-xc.rs extern crate use_from_trait_xc; diff --git a/src/test/ui/useless_comment.rs b/src/test/ui/useless-comment.rs similarity index 100% rename from src/test/ui/useless_comment.rs rename to src/test/ui/useless-comment.rs diff --git a/src/test/ui/useless_comment.stderr b/src/test/ui/useless-comment.stderr similarity index 85% rename from src/test/ui/useless_comment.stderr rename to src/test/ui/useless-comment.stderr index 10d8ee60f99f6..925e307963692 100644 --- a/src/test/ui/useless_comment.stderr +++ b/src/test/ui/useless-comment.stderr @@ -1,5 +1,5 @@ error: unused doc comment - --> $DIR/useless_comment.rs:9:1 + --> $DIR/useless-comment.rs:9:1 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,14 +7,14 @@ LL | mac!(); | ------- rustdoc does not generate documentation for macro expansions | note: lint level defined here - --> $DIR/useless_comment.rs:3:9 + --> $DIR/useless-comment.rs:3:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless_comment.rs:13:5 + --> $DIR/useless-comment.rs:13:5 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | let x = 12; | ----------- rustdoc does not generate documentation for statements error: unused doc comment - --> $DIR/useless_comment.rs:16:5 + --> $DIR/useless-comment.rs:16:5 | LL | / /// multi-line LL | | /// doc comment @@ -36,7 +36,7 @@ LL | | } | |_____- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:20:9 + --> $DIR/useless-comment.rs:20:9 | LL | /// c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | 1 => {}, | ------- rustdoc does not generate documentation for match arms error: unused doc comment - --> $DIR/useless_comment.rs:25:5 + --> $DIR/useless-comment.rs:25:5 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | unsafe {} | --------- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:28:5 + --> $DIR/useless-comment.rs:28:5 | LL | #[doc = "foo"] | ^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | 3; | - rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:29:5 + --> $DIR/useless-comment.rs:29:5 | LL | #[doc = "bar"] | ^^^^^^^^^^^^^^ @@ -69,7 +69,7 @@ LL | 3; | - rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:32:5 + --> $DIR/useless-comment.rs:32:5 | LL | /// bar | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,13 +79,13 @@ LL | mac!(); = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless_comment.rs:35:13 + --> $DIR/useless-comment.rs:35:13 | LL | let x = /** comment */ 47; | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions error: unused doc comment - --> $DIR/useless_comment.rs:37:5 + --> $DIR/useless-comment.rs:37:5 | LL | /// dox | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/xc-private-method.rs b/src/test/ui/xc-private-method.rs index 157249194a345..e95cab93d750e 100644 --- a/src/test/ui/xc-private-method.rs +++ b/src/test/ui/xc-private-method.rs @@ -1,4 +1,4 @@ -// aux-build:xc_private_method_lib.rs +// aux-build:xc-private-method-lib.rs extern crate xc_private_method_lib; diff --git a/src/test/ui/xc-private-method2.rs b/src/test/ui/xc-private-method2.rs index 6d73570318ae8..f11b251082bf2 100644 --- a/src/test/ui/xc-private-method2.rs +++ b/src/test/ui/xc-private-method2.rs @@ -1,4 +1,4 @@ -// aux-build:xc_private_method_lib.rs +// aux-build:xc-private-method-lib.rs extern crate xc_private_method_lib; From e7b7c417e639a2070ae91c2b84e0574beafb0bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 14 Mar 2019 02:23:08 +0100 Subject: [PATCH 065/157] bootstrap: Default to a sensible llvm-suffix. I used version-channel-sha, hopefully that should work. I checked that bootstrap builds, but I cannot check anything else since the llvm build process is started from cargo, and thus calls clang, and thus I hit the same bug I hope to fix with this change. Hopefully fixes #59034. --- src/bootstrap/lib.rs | 6 ++++++ src/bootstrap/native.rs | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 9317a40545eac..976b30a55c94b 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -241,6 +241,8 @@ pub struct Build { clippy_info: channel::GitInfo, miri_info: channel::GitInfo, rustfmt_info: channel::GitInfo, + in_tree_llvm_info: channel::GitInfo, + emscripten_llvm_info: channel::GitInfo, local_rebuild: bool, fail_fast: bool, doc_tests: DocTests, @@ -363,6 +365,8 @@ impl Build { let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy")); let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri")); let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt")); + let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project")); + let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten")); let mut build = Build { initial_rustc: config.initial_rustc.clone(), @@ -386,6 +390,8 @@ impl Build { clippy_info, miri_info, rustfmt_info, + in_tree_llvm_info, + emscripten_llvm_info, cc: HashMap::new(), cxx: HashMap::new(), ar: HashMap::new(), diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d78670cfe515a..3babbc9e10231 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -18,6 +18,7 @@ use build_helper::output; use cmake; use cc; +use crate::channel; use crate::util::{self, exe}; use build_helper::up_to_date; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -231,7 +232,26 @@ impl Step for Llvm { } if let Some(ref suffix) = builder.config.llvm_version_suffix { - cfg.define("LLVM_VERSION_SUFFIX", suffix); + // Allow version-suffix="" to not define a version suffix at all. + if !suffix.is_empty() { + cfg.define("LLVM_VERSION_SUFFIX", suffix); + } + } else { + let mut default_suffix = format!( + "-rust-{}-{}", + channel::CFG_RELEASE_NUM, + builder.config.channel, + ); + let llvm_info = if self.emscripten { + &builder.emscripten_llvm_info + } else { + &builder.in_tree_llvm_info + }; + if let Some(sha) = llvm_info.sha_short() { + default_suffix.push_str("-"); + default_suffix.push_str(sha); + } + cfg.define("LLVM_VERSION_SUFFIX", default_suffix); } if let Some(ref linker) = builder.config.llvm_use_linker { From 88d43a052a9230230bb263ff0b7b072134203510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 14 Mar 2019 05:53:44 +0100 Subject: [PATCH 066/157] Don't run test launching `echo` since that doesn't exist on Windows --- src/libstd/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 568400093440c..ad86acbb47de4 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -8,7 +8,7 @@ //! //! The [`Command`] struct is used to configure and spawn processes: //! -//! ``` +//! ```no_run //! use std::process::Command; //! //! let output = Command::new("echo") From 41cdf07483ed39ccd85ce1c9ae7512ceb3bbb657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 14 Mar 2019 06:35:48 +0100 Subject: [PATCH 067/157] Run RustdocUi earlier --- src/bootstrap/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ffd23e72e80a6..daa6749f87f3e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -408,11 +408,11 @@ impl<'a> Builder<'a> { test::RustdocJSStd, test::RustdocJSNotStd, test::RustdocTheme, + test::RustdocUi, // Run bootstrap close to the end as it's unlikely to fail test::Bootstrap, // Run run-make last, since these won't pass without make on Windows test::RunMake, - test::RustdocUi ), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!( From ab19e5870ea28584ecf3ff4885e29afbbcaf0854 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 14 Mar 2019 23:12:56 +0900 Subject: [PATCH 068/157] Use try blocks in rustc_codegen_ssa --- src/librustc_codegen_ssa/back/linker.rs | 15 ++++++--------- src/librustc_codegen_ssa/lib.rs | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 1f4c5543fa9aa..e6470dbb61ce1 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.target.options.is_like_osx { // Write a plain, newline-separated list of symbols - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); for sym in self.info.exports[&crate_type].iter() { debug!(" _{}", sym); writeln!(f, "_{}", sym)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } } else { // Write an LD version script - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); writeln!(f, "{{\n global:")?; for sym in self.info.exports[&crate_type].iter() { @@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {};", sym)?; } writeln!(f, "\n local:\n *;\n}};")?; - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write version script: {}", e)); } @@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> { tmpdir: &Path, crate_type: CrateType) { let path = tmpdir.join("lib.def"); - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); // Start off with the standard module name header and then go @@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index fec41936a2384..fe9b88c85f009 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -7,6 +7,7 @@ #![feature(libc)] #![feature(rustc_diagnostic_macros)] #![feature(stmt_expr_attributes)] +#![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] #![allow(unused_attributes)] From 51bbf3069854ae79a517ab680488821197e55f9c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 14 Mar 2019 15:25:23 +0100 Subject: [PATCH 069/157] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index e3527fdba7178..72b4ee0381dec 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit e3527fdba7178120a6398e76aa4b3908b10ef85e +Subproject commit 72b4ee0381decf609204e5548c1f5e79bdfb18b7 From f364f483a3d79248b2b6b576097e27ffdacfe38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 14 Mar 2019 16:55:47 +0100 Subject: [PATCH 070/157] Address final review --- src/ci/docker/scripts/musl-toolchain.sh | 6 ++++++ src/ci/docker/test-various/Dockerfile | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 7802e15f18840..e168760f44971 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -1,3 +1,9 @@ +# This script runs `musl-cross-make` to prepare C toolchain (Binutils, GCC, musl itself) +# and builds static libunwind that we distribute for static target. +# +# Versions of the toolchain components are configurable in `musl-cross-make/Makefile` and +# musl unlike GLIBC is forward compatible so upgrading it shouldn't break old distributions. +# Right now we have: Binutils 2.27, GCC 6.3.0, musl 1.1.18 set -ex hide_output() { diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile index 80c6ed68cb547..60b431ad38641 100644 --- a/src/ci/docker/test-various/Dockerfile +++ b/src/ci/docker/test-various/Dockerfile @@ -12,7 +12,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ sudo \ gdb \ xz-utils \ - # for musl wget \ patch @@ -25,9 +24,7 @@ RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \ WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ -RUN CFLAGS="-Wa,-mrelax-relocations=no" \ - CXXFLAGS="-Wa,-mrelax-relocations=no" \ - bash musl-toolchain.sh x86_64 && rm -rf build +RUN bash musl-toolchain.sh x86_64 && rm -rf build WORKDIR / COPY scripts/sccache.sh /scripts/ From d1fcd867386f40af25cd66f5d4a2dfcd028d858d Mon Sep 17 00:00:00 2001 From: lukaslueg Date: Thu, 14 Mar 2019 17:06:46 +0100 Subject: [PATCH 071/157] Update sources.rs The current language may be amusing, yet is just imprecise and most especially difficult to understand for someone who speaks English as a foreign language. --- src/libcore/iter/sources.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 74ff7f41d76fa..ffc24df3ed42e 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -39,8 +39,7 @@ unsafe impl TrustedLen for Repeat {} /// Creates a new iterator that endlessly repeats a single element. /// -/// The `repeat()` function repeats a single value over and over and over and -/// over and over and 🔁. +/// The `repeat()` function repeats a single value over and over again. /// /// Infinite iterators like `repeat()` are often used with adapters like /// [`take`], in order to make them finite. @@ -128,8 +127,7 @@ unsafe impl A> TrustedLen for RepeatWith {} /// Creates a new iterator that repeats elements of type `A` endlessly by /// applying the provided closure, the repeater, `F: FnMut() -> A`. /// -/// The `repeat_with()` function calls the repeater over and over and over and -/// over and over and 🔁. +/// The `repeat_with()` function calls the repeater over and over again. /// /// Infinite iterators like `repeat_with()` are often used with adapters like /// [`take`], in order to make them finite. From fa8fd3daa7efefd4036a377f48f755be0b6952ee Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 14 Mar 2019 15:05:49 -0700 Subject: [PATCH 072/157] Add support for comma-separated option lists --- src/librustc/session/config.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 55c4b0e54b822..d39057cbf92ed 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -800,6 +800,7 @@ macro_rules! options { pub const parse_opt_pathbuf: Option<&str> = Some("a path"); pub const parse_list: Option<&str> = Some("a space-separated list of strings"); pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings"); pub const parse_uint: Option<&str> = Some("a number"); pub const parse_passes: Option<&str> = Some("a space-separated list of passes, or `all`"); @@ -926,6 +927,18 @@ macro_rules! options { } } + fn parse_opt_comma_list(slot: &mut Option>, v: Option<&str>) + -> bool { + match v { + Some(s) => { + let v = s.split(',').map(|s| s.to_string()).collect(); + *slot = Some(v); + true + }, + None => false, + } + } + fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(i) => { *slot = i; true }, From 7c59ce9f5db9cb7dbfbd07fab625e2b67aa042f5 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 13 Mar 2019 16:29:24 -0700 Subject: [PATCH 073/157] Add `-Z allow_features=...` flag --- src/librustc/session/config.rs | 6 ++++++ src/librustc_interface/passes.rs | 1 + src/libsyntax/config.rs | 6 +++--- src/libsyntax/diagnostic_list.rs | 15 +++++++++++++ src/libsyntax/feature_gate.rs | 11 +++++++++- .../ui/feature-gate/allow-features-empty.rs | 10 +++++++++ .../feature-gate/allow-features-empty.stderr | 21 +++++++++++++++++++ src/test/ui/feature-gate/allow-features.rs | 10 +++++++++ .../ui/feature-gate/allow-features.stderr | 9 ++++++++ 9 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/feature-gate/allow-features-empty.rs create mode 100644 src/test/ui/feature-gate/allow-features-empty.stderr create mode 100644 src/test/ui/feature-gate/allow-features.rs create mode 100644 src/test/ui/feature-gate/allow-features.stderr diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d39057cbf92ed..ff18678f091b9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1440,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, merge_functions: Option = (None, parse_merge_functions, [TRACKED], "control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name"), + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (space separated)"), } pub fn default_lib_output() -> CrateType { @@ -3286,6 +3288,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 5bb47bda17b33..0c710fd283be8 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -243,6 +243,7 @@ pub fn register_plugins<'a>( krate, &sess.parse_sess, sess.edition(), + &sess.opts.debugging_opts.allow_features, ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4e4432a3f334d..2abb7e407eb02 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) - -> (ast::Crate, Features) { +pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition, + allow_features: &Option>) -> (ast::Crate, Features) { let features; { let mut strip_unconfigured = StripUnconfigured { @@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, edition); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2c367f1f40242..ac24475cab89f 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -378,6 +378,21 @@ Erroneous code example: "##, +E0725: r##" +A feature attribute named a feature that was disallowed in the compiler +command line flags. + +Erroneous code example: + +```ignore (can't specify compiler flags from doctests) +#![feature(never_type)] // error: the feature `never_type` is not in + // the list of allowed features +``` + +Delete the offending feature attribute, or add it to the list of allowed +features in the `-Z allow_features` flag. +"##, + } register_diagnostics! { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 279e2089f5d71..77e8e75d8321b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - crate_edition: Edition) -> Features { + crate_edition: Edition, allow_features: &Option>) -> Features { fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); if let Some(reason) = reason { @@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|f| *f == name.as_str()).is_none() { + span_err!(span_handler, mi.span, E0725, + "the feature `{}` is not in the list of allowed features", + name); + continue; + } + } + set(&mut features, mi.span); features.declared_lang_features.push((name, mi.span, None)); continue diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs new file mode 100644 index 0000000000000..83250052cb506 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features= +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] //~ ERROR + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] //~ ERROR + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr new file mode 100644 index 0000000000000..cce2c4078c242 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.stderr @@ -0,0 +1,21 @@ +error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:4:12 + | +LL | #![feature(rustc_diagnostic_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `lang_items` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:8:12 + | +LL | #![feature(lang_items)] + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs new file mode 100644 index 0000000000000..1cebc8f34f26f --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr new file mode 100644 index 0000000000000..b13560fb81c6a --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.stderr @@ -0,0 +1,9 @@ +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0725`. From 451343e0f3d90904bdc2080cc8bc4eb00be0364e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 15 Mar 2019 01:19:54 +0100 Subject: [PATCH 074/157] Fix TARGET variable in musl-toolchain.sh --- src/ci/docker/scripts/musl-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index e168760f44971..95b7c2869c91f 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -24,7 +24,7 @@ exit 1 } ARCH=$1 -TARGET=linux-musl-$ARCH +TARGET=$ARCH-linux-musl OUTPUT=/usr/local shift From bcf1a179aed651fe27fef7578bfc25b063a33a8e Mon Sep 17 00:00:00 2001 From: O01eg Date: Fri, 15 Mar 2019 08:50:08 +0300 Subject: [PATCH 075/157] Output diagnostic information for rustdoc. Use the information same as rustc. --- src/bootstrap/bin/rustdoc.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 36beec3a944a0..085f243785cbe 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -35,7 +35,7 @@ fn main() { .arg("--cfg") .arg("dox") .arg("--sysroot") - .arg(sysroot) + .arg(&sysroot) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); @@ -72,7 +72,13 @@ fn main() { } if verbose > 1 { - eprintln!("rustdoc command: {:?}", cmd); + eprintln!( + "rustdoc command: {:?}={:?} {:?}", + bootstrap::util::dylib_path_var(), + env::join_paths(&dylib_path).unwrap(), + cmd, + ); + eprintln!("sysroot: {:?}", sysroot); eprintln!("libdir: {:?}", libdir); } From 228d6f45d8fbf289e6505d12379a41e13a0872a1 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 9 Dec 2018 22:42:08 +0200 Subject: [PATCH 076/157] rustc: remove unnecessary extern_prelude logic from ty::item_path. --- src/librustc/ty/item_path.rs | 107 +++++++++------------ src/librustc_codegen_utils/symbol_names.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- 3 files changed, 47 insertions(+), 64 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 26e2705a7a034..6734e264305a7 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }); let mut buffer = LocalPathBuffer::new(mode); debug!("item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id, false); + self.push_item_path(&mut buffer, def_id); buffer.into_string() } @@ -81,19 +81,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn absolute_item_path_str(self, def_id: DefId) -> String { let mut buffer = LocalPathBuffer::new(RootMode::Absolute); debug!("absolute_item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id, false); + self.push_item_path(&mut buffer, def_id); buffer.into_string() } /// Returns the "path" to a particular crate. This can proceed in /// various ways, depending on the `root_mode` of the `buffer`. /// (See `RootMode` enum for more details.) - /// - /// `pushed_prelude_crate` argument should be `true` when the buffer - /// has had a prelude crate pushed to it. If this is the case, then - /// we do not want to prepend `crate::` (as that would not be a valid - /// path). - pub fn push_krate_path(self, buffer: &mut T, cnum: CrateNum, pushed_prelude_crate: bool) + pub fn push_krate_path(self, buffer: &mut T, cnum: CrateNum) where T: ItemPathBuffer + Debug { debug!( @@ -115,28 +110,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // // Returns `None` for the local crate. if cnum != LOCAL_CRATE { - let opt_extern_crate = self.extern_crate(cnum.as_def_id()); - if let Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - .. - }) = *opt_extern_crate - { - debug!("push_krate_path: def_id={:?}", def_id); - self.push_item_path(buffer, def_id, pushed_prelude_crate); - } else { - let name = self.crate_name(cnum).as_str(); - debug!("push_krate_path: name={:?}", name); - buffer.push(&name); - } - } else if self.sess.rust_2018() && !pushed_prelude_crate { - SHOULD_PREFIX_WITH_CRATE.with(|flag| { - // We only add the `crate::` keyword where appropriate. In particular, - // when we've not previously pushed a prelude crate to this path. - if flag.get() { - buffer.push(&keywords::Crate.name().as_str()) + match *self.extern_crate(cnum.as_def_id()) { + Some(ExternCrate { + src: ExternCrateSource::Extern(def_id), + direct: true, + span, + .. + }) if !span.is_dummy() => { + debug!("push_krate_path: def_id={:?}", def_id); + self.push_item_path(buffer, def_id); } - }) + _ => { + let name = self.crate_name(cnum).as_str(); + debug!("push_krate_path: name={:?}", name); + buffer.push(&name); + } + } + } else if self.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + buffer.push(&keywords::Crate.name().as_str()) + } } } RootMode::Absolute => { @@ -156,7 +150,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, buffer: &mut T, external_def_id: DefId, - pushed_prelude_crate: bool, ) -> bool where T: ItemPathBuffer + Debug { @@ -179,10 +172,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Some(ExternCrate { src: ExternCrateSource::Extern(def_id), direct: true, + span, .. }) => { debug!("try_push_visible_item_path: def_id={:?}", def_id); - self.push_item_path(buffer, def_id, pushed_prelude_crate); + if !span.is_dummy() { + self.push_item_path(buffer, def_id); + } else { + buffer.push(&self.crate_name(cur_def.krate).as_str()); + } cur_path.iter().rev().for_each(|segment| buffer.push(&segment)); return true; } @@ -280,16 +278,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn push_item_path(self, buffer: &mut T, def_id: DefId, pushed_prelude_crate: bool) + pub fn push_item_path(self, buffer: &mut T, def_id: DefId) where T: ItemPathBuffer + Debug { debug!( - "push_item_path: buffer={:?} def_id={:?} pushed_prelude_crate={:?}", - buffer, def_id, pushed_prelude_crate + "push_item_path: buffer={:?} def_id={:?}", + buffer, def_id ); match *buffer.root_mode() { RootMode::Local if !def_id.is_local() => - if self.try_push_visible_item_path(buffer, def_id, pushed_prelude_crate) { return }, + if self.try_push_visible_item_path(buffer, def_id) { return }, _ => {} } @@ -298,11 +296,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); - self.push_krate_path(buffer, def_id.krate, pushed_prelude_crate); + self.push_krate_path(buffer, def_id.krate); } DefPathData::Impl => { - self.push_impl_path(buffer, def_id, pushed_prelude_crate); + self.push_impl_path(buffer, def_id); } // Unclear if there is any value in distinguishing these. @@ -327,36 +325,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::ClosureExpr | data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.parent_def_id(def_id).unwrap(); - - // Keep track of whether we are one recursion away from the `CrateRoot` and - // pushing the name of a prelude crate. If we are, we'll want to know this when - // printing the `CrateRoot` so we don't prepend a `crate::` to paths. - let mut is_prelude_crate = false; - if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data { - if self.extern_prelude.contains_key(&data.as_interned_str().as_symbol()) { - is_prelude_crate = true; - } - } - - self.push_item_path( - buffer, parent_did, pushed_prelude_crate || is_prelude_crate - ); + let parent_def_id = self.parent_def_id(def_id).unwrap(); + self.push_item_path(buffer, parent_def_id); buffer.push(&data.as_interned_str().as_symbol().as_str()); }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.parent_def_id(def_id).unwrap(); - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); + self.push_item_path(buffer, parent_def_id); } } } fn push_impl_path( self, - buffer: &mut T, - impl_def_id: DefId, - pushed_prelude_crate: bool, + buffer: &mut T, + impl_def_id: DefId, ) where T: ItemPathBuffer + Debug { @@ -372,7 +356,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; if !use_types { - return self.push_impl_path_fallback(buffer, impl_def_id, pushed_prelude_crate); + return self.push_impl_path_fallback(buffer, impl_def_id); } // Decide whether to print the parent path for the impl. @@ -396,7 +380,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); + self.push_item_path(buffer, parent_def_id); if let Some(trait_ref) = impl_trait_ref { buffer.push(&format!("", trait_ref, self_ty)); } else { @@ -420,13 +404,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match self_ty.sty { ty::Adt(adt_def, substs) => { if substs.types().next().is_none() { // ignore regions - self.push_item_path(buffer, adt_def.did, pushed_prelude_crate); + self.push_item_path(buffer, adt_def.did); } else { buffer.push(&format!("<{}>", self_ty)); } } - ty::Foreign(did) => self.push_item_path(buffer, did, pushed_prelude_crate), + ty::Foreign(did) => self.push_item_path(buffer, did), ty::Bool | ty::Char | @@ -447,7 +431,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, buffer: &mut T, impl_def_id: DefId, - pushed_prelude_crate: bool, ) where T: ItemPathBuffer + Debug { @@ -455,7 +438,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // pretty printing some span information. This should // only occur very early in the compiler pipeline. let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); - self.push_item_path(buffer, parent_def_id, pushed_prelude_crate); + self.push_item_path(buffer, parent_def_id); let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap(); let item = self.hir().expect_item_by_hir_id(hir_id); let span_str = self.sess.source_map().span_to_string(item.span); diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 5de5c297c30e5..91301158abdb0 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -225,7 +225,7 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { let mut buffer = SymbolPathBuffer::new(tcx); item_path::with_forced_absolute_paths(|| { - tcx.push_item_path(&mut buffer, def_id, false); + tcx.push_item_path(&mut buffer, def_id); }); buffer.into_interned() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f2bf7ead5619b..af40e417d6108 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4243,7 +4243,7 @@ where F: Fn(DefId) -> Def { let mut apb = AbsolutePathBuffer { names: vec![] }; - tcx.push_item_path(&mut apb, def_id, false); + tcx.push_item_path(&mut apb, def_id); hir::Path { span: DUMMY_SP, From 382d24e7d73e36fa150866051e700a2307916f77 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 4 Dec 2018 19:13:37 +0200 Subject: [PATCH 077/157] rustc: start moving util::ppaux to ty::print. --- src/librustc/ty/mod.rs | 1 + src/librustc/ty/print.rs | 91 ++++++++++++++++++++++++++++++++++++++ src/librustc/util/ppaux.rs | 84 +---------------------------------- 3 files changed, 93 insertions(+), 83 deletions(-) create mode 100644 src/librustc/ty/print.rs diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 68bdae7d744c5..23fa81f77df28 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -99,6 +99,7 @@ pub mod item_path; pub mod layout; pub mod _match; pub mod outlives; +pub mod print; pub mod query; pub mod relate; pub mod steal; diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs new file mode 100644 index 0000000000000..f58bb2824d1d2 --- /dev/null +++ b/src/librustc/ty/print.rs @@ -0,0 +1,91 @@ +use crate::ty::{self, TypeFoldable}; + +use rustc_data_structures::fx::FxHashSet; +use syntax::symbol::InternedString; + +use std::fmt; + +// FIXME(eddyb) this module uses `pub(crate)` for things used only +// from `ppaux` - when that is removed, they can be re-privatized. + +struct LateBoundRegionNameCollector(FxHashSet); +impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + match *r { + ty::ReLateBound(_, ty::BrNamed(_, name)) => { + self.0.insert(name); + }, + _ => {}, + } + r.super_visit_with(self) + } +} + +#[derive(Debug)] +pub struct PrintContext { + pub(crate) is_debug: bool, + pub(crate) is_verbose: bool, + pub(crate) identify_regions: bool, + pub(crate) used_region_names: Option>, + pub(crate) region_index: usize, + pub(crate) binder_depth: usize, +} + +impl PrintContext { + pub(crate) fn new() -> Self { + ty::tls::with_opt(|tcx| { + let (is_verbose, identify_regions) = tcx.map( + |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions) + ).unwrap_or((false, false)); + PrintContext { + is_debug: false, + is_verbose: is_verbose, + identify_regions: identify_regions, + used_region_names: None, + region_index: 0, + binder_depth: 0, + } + }) + } + pub(crate) fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder) + where T: TypeFoldable<'tcx> + { + let mut collector = LateBoundRegionNameCollector(Default::default()); + value.visit_with(&mut collector); + self.used_region_names = Some(collector.0); + self.region_index = 0; + } +} + +pub trait Print { + fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print(&mut result, cx); + result + } + fn print_display(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + let old_debug = cx.is_debug; + cx.is_debug = false; + let result = self.print(f, cx); + cx.is_debug = old_debug; + result + } + fn print_display_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print_display(&mut result, cx); + result + } + fn print_debug(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + let old_debug = cx.is_debug; + cx.is_debug = true; + let result = self.print(f, cx); + cx.is_debug = old_debug; + result + } + fn print_debug_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print_debug(&mut result, cx); + result + } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a1398c69ff0c5..24b9779654a20 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,8 +9,8 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; +use crate::ty::print::{PrintContext, Print}; use crate::mir::interpret::ConstValue; -use crate::util::nodemap::FxHashSet; use std::cell::Cell; use std::fmt; @@ -275,88 +275,6 @@ macro_rules! print { }; } - -struct LateBoundRegionNameCollector(FxHashSet); -impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { - fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - match *r { - ty::ReLateBound(_, ty::BrNamed(_, name)) => { - self.0.insert(name); - }, - _ => {}, - } - r.super_visit_with(self) - } -} - -#[derive(Debug)] -pub struct PrintContext { - is_debug: bool, - is_verbose: bool, - identify_regions: bool, - used_region_names: Option>, - region_index: usize, - binder_depth: usize, -} -impl PrintContext { - fn new() -> Self { - ty::tls::with_opt(|tcx| { - let (is_verbose, identify_regions) = tcx.map( - |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions) - ).unwrap_or((false, false)); - PrintContext { - is_debug: false, - is_verbose: is_verbose, - identify_regions: identify_regions, - used_region_names: None, - region_index: 0, - binder_depth: 0, - } - }) - } - fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder) - where T: TypeFoldable<'tcx> - { - let mut collector = LateBoundRegionNameCollector(Default::default()); - value.visit_with(&mut collector); - self.used_region_names = Some(collector.0); - self.region_index = 0; - } -} - -pub trait Print { - fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print(&mut result, cx); - result - } - fn print_display(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { - let old_debug = cx.is_debug; - cx.is_debug = false; - let result = self.print(f, cx); - cx.is_debug = old_debug; - result - } - fn print_display_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print_display(&mut result, cx); - result - } - fn print_debug(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { - let old_debug = cx.is_debug; - cx.is_debug = true; - let result = self.print(f, cx); - cx.is_debug = old_debug; - result - } - fn print_debug_to_string(&self, cx: &mut PrintContext) -> String { - let mut result = String::new(); - let _ = self.print_debug(&mut result, cx); - result - } -} - impl PrintContext { fn fn_sig(&mut self, f: &mut F, From 297546e62db0ec681482baf31d0bd6dd733fdd39 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 4 Dec 2018 19:13:55 +0200 Subject: [PATCH 078/157] rustc: add a 'tcx parameter to Print. --- src/librustc/ty/print.rs | 2 +- src/librustc/util/ppaux.rs | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index f58bb2824d1d2..569d9d7a3ac84 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -57,7 +57,7 @@ impl PrintContext { } } -pub trait Print { +pub trait Print<'tcx> { fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; fn print_to_string(&self, cx: &mut PrintContext) -> String { let mut result = String::new(); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 24b9779654a20..9fc4b17995417 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -212,7 +212,7 @@ macro_rules! gen_display_debug { } macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl<$($x)+> Print for $target { + impl<$($x)+> Print<'tcx> for $target { fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -220,7 +220,7 @@ macro_rules! gen_print_impl { } }; ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl Print for $target { + impl Print<'tcx> for $target { fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -527,12 +527,15 @@ impl PrintContext { Ok(()) } - fn in_binder<'a, 'gcx, 'tcx, T, U, F>(&mut self, - f: &mut F, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - original: &ty::Binder, - lifted: Option>) -> fmt::Result - where T: Print, U: Print + TypeFoldable<'tcx>, F: fmt::Write + // FIXME(eddyb) replace `'almost_tcx` with `'tcx` when possible/needed. + fn in_binder<'a, 'gcx, 'tcx, 'almost_tcx, T, U, F>( + &mut self, + f: &mut F, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + original: &ty::Binder, + lifted: Option>, + ) -> fmt::Result + where T: Print<'almost_tcx>, U: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -627,7 +630,7 @@ pub fn parameterized(f: &mut F, PrintContext::new().parameterized(f, substs, did, projections) } -impl<'a, T: Print> Print for &'a T { +impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { (*self).print(f, cx) } @@ -1466,7 +1469,7 @@ define_print! { } define_print! { - ('tcx, T: Print + fmt::Debug, U: Print + fmt::Debug) ty::OutlivesPredicate, + ('tcx, T: Print<'tcx> + fmt::Debug, U: Print<'tcx> + fmt::Debug) ty::OutlivesPredicate, (self, f, cx) { display { print!(f, cx, print(self.0), write(" : "), print(self.1)) From 372b1a5930f3dc2b878ae0ed3c0d939451c8ac24 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 4 Dec 2018 19:25:17 +0200 Subject: [PATCH 079/157] rustc: uniformize all lift expect messages to "could not lift for printing". --- src/librustc/util/ppaux.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 9fc4b17995417..dc3160b7ab97f 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -648,11 +648,11 @@ define_print! { if let Some(principal) = self.principal() { let principal = tcx .lift(&principal) - .expect("could not lift TraitRef for printing") + .expect("could not lift for printing") .with_self_ty(tcx, dummy_self); let projections = self.projection_bounds().map(|p| { tcx.lift(&p) - .expect("could not lift projection for printing") + .expect("could not lift for printing") .with_self_ty(tcx, dummy_self) }).collect::>(); cx.parameterized(f, principal.substs, principal.def_id, &projections)?; @@ -781,7 +781,7 @@ define_print! { let dummy_self = tcx.mk_infer(ty::FreshTy(0)); let trait_ref = *tcx.lift(&ty::Binder::bind(*self)) - .expect("could not lift TraitRef for printing") + .expect("could not lift for printing") .with_self_ty(tcx, dummy_self).skip_binder(); cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) }) From 852fc6d2b61e7b1f45f2679d025b824af70f89b1 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 4 Dec 2018 19:35:48 +0200 Subject: [PATCH 080/157] rustc: don't support `tcx.lift` returning `None` in ppaux. --- src/librustc/util/ppaux.rs | 57 ++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index dc3160b7ab97f..0dc1aea0a9682 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -404,17 +404,16 @@ impl PrintContext { *has_default.unwrap_or(&false) }; if has_default { - if let Some(substs) = tcx.lift(&substs) { - let types = substs.types().rev().skip(child_types); - for ((def_id, has_default), actual) in type_params.zip(types) { - if !has_default { - break; - } - if tcx.type_of(def_id).subst(tcx, substs) != actual { - break; - } - num_supplied_defaults += 1; + let substs = tcx.lift(&substs).expect("could not lift for printing"); + let types = substs.types().rev().skip(child_types); + for ((def_id, has_default), actual) in type_params.zip(types) { + if !has_default { + break; } + if tcx.type_of(def_id).subst(tcx, substs) != actual { + break; + } + num_supplied_defaults += 1; } } } @@ -527,15 +526,13 @@ impl PrintContext { Ok(()) } - // FIXME(eddyb) replace `'almost_tcx` with `'tcx` when possible/needed. - fn in_binder<'a, 'gcx, 'tcx, 'almost_tcx, T, U, F>( + fn in_binder<'a, 'gcx, 'tcx, T, F>( &mut self, f: &mut F, tcx: TyCtxt<'a, 'gcx, 'tcx>, - original: &ty::Binder, - lifted: Option>, + value: ty::Binder, ) -> fmt::Result - where T: Print<'almost_tcx>, U: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write + where T: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -550,12 +547,6 @@ impl PrintContext { // clearly differentiate between named and unnamed regions in // the output. We'll probably want to tweak this over time to // decide just how much information to give. - let value = if let Some(v) = lifted { - v - } else { - return original.skip_binder().print_display(f, self); - }; - if self.binder_depth == 0 { self.prepare_late_bound_region_info(&value); } @@ -1101,7 +1092,8 @@ impl fmt::Debug for ty::FloatVarValue { for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) + ty::tls::with(|tcx| in_binder(f, tcx, tcx.lift(self) + .expect("could not lift for printing"))) } }*/ @@ -1118,7 +1110,8 @@ define_print_multi! { ] (self, f, cx) { display { - ty::tls::with(|tcx| cx.in_binder(f, tcx, self, tcx.lift(self))) + ty::tls::with(|tcx| cx.in_binder(f, tcx, tcx.lift(self) + .expect("could not lift for printing"))) } } } @@ -1186,10 +1179,9 @@ define_print! { } FnDef(def_id, substs) => { ty::tls::with(|tcx| { - let mut sig = tcx.fn_sig(def_id); - if let Some(substs) = tcx.lift(&substs) { - sig = sig.subst(tcx, substs); - } + let substs = tcx.lift(&substs) + .expect("could not lift for printing"); + let sig = tcx.fn_sig(def_id).subst(tcx, substs); print!(f, cx, print(sig), write(" {{")) })?; cx.parameterized(f, substs, def_id, &[])?; @@ -1260,11 +1252,9 @@ define_print! { } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let predicates_of = tcx.predicates_of(def_id); - let substs = tcx.lift(&substs).unwrap_or_else(|| { - tcx.intern_substs(&[]) - }); - let bounds = predicates_of.instantiate(tcx, substs); + let substs = tcx.lift(&substs) + .expect("could not lift for printing"); + let bounds = tcx.predicates_of(def_id).instantiate(tcx, substs); let mut first = true; let mut is_sized = false; @@ -1331,7 +1321,8 @@ define_print! { print!(f, cx, write(" "), print(witness), write("]")) }), GeneratorWitness(types) => { - ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types))) + ty::tls::with(|tcx| cx.in_binder(f, tcx, tcx.lift(&types) + .expect("could not lift for printing"))) } Closure(did, substs) => ty::tls::with(|tcx| { let upvar_tys = substs.upvar_tys(did, tcx); From c6848141026853e8d59cf8b6f3a3bb2f76e06128 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 4 Dec 2018 20:04:21 +0200 Subject: [PATCH 081/157] rustc: don't support missing TLS TyCtxt in ty::print. --- src/librustc/ty/print.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 569d9d7a3ac84..5f46806e1599f 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -33,10 +33,9 @@ pub struct PrintContext { impl PrintContext { pub(crate) fn new() -> Self { - ty::tls::with_opt(|tcx| { - let (is_verbose, identify_regions) = tcx.map( - |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions) - ).unwrap_or((false, false)); + ty::tls::with(|tcx| { + let (is_verbose, identify_regions) = + (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions); PrintContext { is_debug: false, is_verbose: is_verbose, From 5f3841ca2fe5cf0ba714db42a29a8004a878b6e6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 16:17:44 +0200 Subject: [PATCH 082/157] rustc: rename PrintContext to PrintCx. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/ty/print.rs | 18 +++++++++--------- src/librustc/util/ppaux.rs | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c7936534aad2e..ebed768fa54ec 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -683,7 +683,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// For generic types with parameters with defaults, remove the parameters corresponding to - /// the defaults. This repeats a lot of the logic found in `PrintContext::parameterized`. + /// the defaults. This repeats a lot of the logic found in `PrintCx::parameterized`. fn strip_generic_default_params( &self, def_id: DefId, diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 5f46806e1599f..3d6dec8a141f7 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -22,7 +22,7 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } #[derive(Debug)] -pub struct PrintContext { +pub struct PrintCx { pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, @@ -31,12 +31,12 @@ pub struct PrintContext { pub(crate) binder_depth: usize, } -impl PrintContext { +impl PrintCx { pub(crate) fn new() -> Self { ty::tls::with(|tcx| { let (is_verbose, identify_regions) = (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions); - PrintContext { + PrintCx { is_debug: false, is_verbose: is_verbose, identify_regions: identify_regions, @@ -57,32 +57,32 @@ impl PrintContext { } pub trait Print<'tcx> { - fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintContext) -> String { + fn print(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintCx) -> String { let mut result = String::new(); let _ = self.print(&mut result, cx); result } - fn print_display(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + fn print_display(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = false; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_display_to_string(&self, cx: &mut PrintContext) -> String { + fn print_display_to_string(&self, cx: &mut PrintCx) -> String { let mut result = String::new(); let _ = self.print_display(&mut result, cx); result } - fn print_debug(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + fn print_debug(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_debug_to_string(&self, cx: &mut PrintContext) -> String { + fn print_debug_to_string(&self, cx: &mut PrintCx) -> String { let mut result = String::new(); let _ = self.print_debug(&mut result, cx); result diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0dc1aea0a9682..683e0aa0dab62 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,7 +9,7 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; -use crate::ty::print::{PrintContext, Print}; +use crate::ty::print::{PrintCx, Print}; use crate::mir::interpret::ConstValue; use std::cell::Cell; @@ -182,7 +182,7 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut cx = PrintContext::new(); + let mut cx = PrintCx::new(); $with(self, f, &mut cx) } }; @@ -213,7 +213,7 @@ macro_rules! gen_display_debug { macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { impl<$($x)+> Print<'tcx> for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { + fn print(&$self, $f: &mut F, $cx: &mut PrintCx) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -221,7 +221,7 @@ macro_rules! gen_print_impl { }; ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { impl Print<'tcx> for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { + fn print(&$self, $f: &mut F, $cx: &mut PrintCx) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -275,7 +275,7 @@ macro_rules! print { }; } -impl PrintContext { +impl PrintCx { fn fn_sig(&mut self, f: &mut F, inputs: &[Ty<'_>], @@ -618,11 +618,11 @@ pub fn parameterized(f: &mut F, did: DefId, projections: &[ty::ProjectionPredicate<'_>]) -> fmt::Result { - PrintContext::new().parameterized(f, substs, did, projections) + PrintCx::new().parameterized(f, substs, did, projections) } impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + fn print(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { (*self).print(f, cx) } } From 0b3ab4018b41c42ce29c265fb8c06b13ac90b355 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 15:22:50 +0200 Subject: [PATCH 083/157] rustc: keep a TyCtxt in PrintCx and use it instead of ty::tls. --- src/librustc/mir/mod.rs | 24 +-- src/librustc/ty/print.rs | 35 ++-- src/librustc/util/ppaux.rs | 339 +++++++++++++++++-------------------- 3 files changed, 190 insertions(+), 208 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3a4422a62390b..b04bb5b3d0171 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,17 +2369,19 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - let region = if ppaux::verbose() || ppaux::identify_regions() { - let mut region = region.to_string(); - if region.len() > 0 { - region.push(' '); - } - region - } else { - // Do not even print 'static - String::new() - }; - write!(fmt, "&{}{}{:?}", region, kind_str, place) + ty::print::PrintCx::with(|cx| { + let region = if cx.is_verbose || cx.identify_regions { + let mut region = region.to_string(); + if region.len() > 0 { + region.push(' '); + } + region + } else { + // Do not even print 'static + String::new() + }; + write!(fmt, "&{}{}{:?}", region, kind_str, place) + }) } Aggregate(ref kind, ref places) => { diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 3d6dec8a141f7..fb296519d4997 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -1,4 +1,4 @@ -use crate::ty::{self, TypeFoldable}; +use crate::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashSet; use syntax::symbol::InternedString; @@ -21,8 +21,8 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } } -#[derive(Debug)] -pub struct PrintCx { +pub struct PrintCx<'a, 'gcx, 'tcx> { + pub(crate) tcx: TyCtxt<'a, 'gcx, 'tcx>, pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, @@ -31,22 +31,21 @@ pub struct PrintCx { pub(crate) binder_depth: usize, } -impl PrintCx { - pub(crate) fn new() -> Self { +impl PrintCx<'a, 'gcx, 'tcx> { + pub(crate) fn with(f: impl FnOnce(PrintCx<'_, '_, '_>) -> R) -> R { ty::tls::with(|tcx| { - let (is_verbose, identify_regions) = - (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions); - PrintCx { + f(PrintCx { + tcx, is_debug: false, - is_verbose: is_verbose, - identify_regions: identify_regions, + is_verbose: tcx.sess.verbose(), + identify_regions: tcx.sess.opts.debugging_opts.identify_regions, used_region_names: None, region_index: 0, binder_depth: 0, - } + }) }) } - pub(crate) fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder) + pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx> { let mut collector = LateBoundRegionNameCollector(Default::default()); @@ -57,32 +56,32 @@ impl PrintCx { } pub trait Print<'tcx> { - fn print(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintCx) -> String { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { let mut result = String::new(); let _ = self.print(&mut result, cx); result } - fn print_display(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { + fn print_display(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = false; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_display_to_string(&self, cx: &mut PrintCx) -> String { + fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { let mut result = String::new(); let _ = self.print_display(&mut result, cx); result } - fn print_debug(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { + fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_debug_to_string(&self, cx: &mut PrintCx) -> String { + fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { let mut result = String::new(); let _ = self.print_debug(&mut result, cx); result diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 683e0aa0dab62..ff66df4e4a3f6 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -8,7 +8,7 @@ use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; +use crate::ty::{self, Ty, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; use crate::ty::print::{PrintCx, Print}; use crate::mir::interpret::ConstValue; @@ -182,8 +182,7 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut cx = PrintCx::new(); - $with(self, f, &mut cx) + PrintCx::with(|mut cx| $with(self, f, &mut cx)) } }; } @@ -213,7 +212,11 @@ macro_rules! gen_display_debug { macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { impl<$($x)+> Print<'tcx> for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintCx) -> fmt::Result { + fn print( + &$self, + $f: &mut F, + $cx: &mut PrintCx<'_, '_, '_>, + ) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -221,7 +224,11 @@ macro_rules! gen_print_impl { }; ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { impl Print<'tcx> for $target { - fn print(&$self, $f: &mut F, $cx: &mut PrintCx) -> fmt::Result { + fn print( + &$self, + $f: &mut F, + $cx: &mut PrintCx<'_, '_, '_>, + ) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -275,7 +282,7 @@ macro_rules! print { }; } -impl PrintCx { +impl PrintCx<'a, 'gcx, 'tcx> { fn fn_sig(&mut self, f: &mut F, inputs: &[Ty<'_>], @@ -307,21 +314,22 @@ impl PrintCx { did: DefId, projections: &[ty::ProjectionPredicate<'_>]) -> fmt::Result { - let key = ty::tls::with(|tcx| tcx.def_key(did)); + let key = self.tcx.def_key(did); let verbose = self.is_verbose; let mut num_supplied_defaults = 0; - let mut has_self = false; + let has_self; let mut own_counts: GenericParamCount = Default::default(); let mut is_value_path = false; let mut item_name = Some(key.disambiguated_data.data.as_interned_str()); - let fn_trait_kind = ty::tls::with(|tcx| { + let mut path_def_id = did; + { // Unfortunately, some kinds of items (e.g., closures) don't have // generics. So walk back up the find the closest parent that DOES // have them. let mut item_def_id = did; loop { - let key = tcx.def_key(item_def_id); + let key = self.tcx.def_key(item_def_id); match key.disambiguated_data.data { DefPathData::AssocTypeInTrait(_) | DefPathData::AssocTypeInImpl(_) | @@ -360,9 +368,8 @@ impl PrintCx { } } } - let mut generics = tcx.generics_of(item_def_id); + let mut generics = self.tcx.generics_of(item_def_id); let child_own_counts = generics.own_counts(); - let mut path_def_id = did; has_self = generics.has_self; let mut child_types = 0; @@ -370,7 +377,7 @@ impl PrintCx { // Methods. assert!(is_value_path); child_types = child_own_counts.types; - generics = tcx.generics_of(def_id); + generics = self.tcx.generics_of(def_id); own_counts = generics.own_counts(); if has_self { @@ -404,23 +411,22 @@ impl PrintCx { *has_default.unwrap_or(&false) }; if has_default { - let substs = tcx.lift(&substs).expect("could not lift for printing"); + let substs = self.tcx.lift(&substs).expect("could not lift for printing"); let types = substs.types().rev().skip(child_types); for ((def_id, has_default), actual) in type_params.zip(types) { if !has_default { break; } - if tcx.type_of(def_id).subst(tcx, substs) != actual { + if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { break; } num_supplied_defaults += 1; } } } - - print!(f, self, write("{}", tcx.item_path_str(path_def_id)))?; - Ok(tcx.lang_items().fn_trait_kind(path_def_id)) - })?; + } + print!(f, self, write("{}", self.tcx.item_path_str(path_def_id)))?; + let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(path_def_id); if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { let projection_ty = projections[0].ty; @@ -482,12 +488,10 @@ impl PrintCx { for projection in projections { start_or_continue(f, "<", ", ")?; - ty::tls::with(|tcx| - print!(f, self, - write("{}=", - tcx.associated_item(projection.projection_ty.item_def_id).ident), - print_display(projection.ty)) - )?; + print!(f, self, + write("{}=", + self.tcx.associated_item(projection.projection_ty.item_def_id).ident), + print_display(projection.ty))?; } // FIXME(const_generics::defaults) @@ -526,12 +530,7 @@ impl PrintCx { Ok(()) } - fn in_binder<'a, 'gcx, 'tcx, T, F>( - &mut self, - f: &mut F, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - value: ty::Binder, - ) -> fmt::Result + fn in_binder(&mut self, f: &mut F, value: ty::Binder) -> fmt::Result where T: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write { fn name_by_region_index(index: usize) -> InternedString { @@ -563,7 +562,7 @@ impl PrintCx { let old_region_index = self.region_index; let mut region_index = old_region_index; - let new_value = tcx.replace_late_bound_regions(&value, |br| { + let new_value = self.tcx.replace_late_bound_regions(&value, |br| { let _ = start_or_continue(f, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { @@ -581,10 +580,10 @@ impl PrintCx { } }; let _ = write!(f, "{}", name); - ty::BrNamed(tcx.hir().local_def_id(CRATE_NODE_ID), name) + ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name) } }; - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) + self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) }).0; start_or_continue(f, "", "> ")?; @@ -605,24 +604,16 @@ impl PrintCx { } } -pub fn verbose() -> bool { - ty::tls::with(|tcx| tcx.sess.verbose()) -} - -pub fn identify_regions() -> bool { - ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions) -} - pub fn parameterized(f: &mut F, substs: SubstsRef<'_>, did: DefId, projections: &[ty::ProjectionPredicate<'_>]) -> fmt::Result { - PrintCx::new().parameterized(f, substs, did, projections) + PrintCx::with(|mut cx| cx.parameterized(f, substs, did, projections)) } impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintCx) -> fmt::Result { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { (*self).print(f, cx) } } @@ -631,50 +622,47 @@ define_print! { ('tcx) &'tcx ty::List>, (self, f, cx) { display { // Generate the main trait ref, including associated types. - ty::tls::with(|tcx| { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - let mut first = true; - - if let Some(principal) = self.principal() { - let principal = tcx - .lift(&principal) - .expect("could not lift for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; - first = false; - } - // Builtin bounds. - let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - tcx.item_path_str(did) - }).collect(); - - // The auto traits come ordered by `DefPathHash`. While - // `DefPathHash` is *stable* in the sense that it depends on - // neither the host nor the phase of the moon, it depends - // "pseudorandomly" on the compiler version and the target. - // - // To avoid that causing instabilities in compiletest - // output, sort the auto-traits alphabetically. - auto_traits.sort(); - - for auto_trait in auto_traits { - if !first { - write!(f, " + ")?; - } - first = false; + // Use a type that can't appear in defaults of type parameters. + let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); + let mut first = true; + + if let Some(principal) = self.principal() { + let principal = cx.tcx + .lift(&principal) + .expect("could not lift for printing") + .with_self_ty(cx.tcx, dummy_self); + let projections = self.projection_bounds().map(|p| { + cx.tcx.lift(&p) + .expect("could not lift for printing") + .with_self_ty(cx.tcx, dummy_self) + }).collect::>(); + cx.parameterized(f, principal.substs, principal.def_id, &projections)?; + first = false; + } - write!(f, "{}", auto_trait)?; + // Builtin bounds. + let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { + cx.tcx.item_path_str(did) + }).collect(); + + // The auto traits come ordered by `DefPathHash`. While + // `DefPathHash` is *stable* in the sense that it depends on + // neither the host nor the phase of the moon, it depends + // "pseudorandomly" on the compiler version and the target. + // + // To avoid that causing instabilities in compiletest + // output, sort the auto-traits alphabetically. + auto_traits.sort(); + + for auto_trait in auto_traits { + if !first { + write!(f, " + ")?; } + first = false; - Ok(()) - })?; + write!(f, "{}", auto_trait)?; + } Ok(()) } @@ -698,16 +686,16 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - write!(f, "{}", tcx.item_path_str(self.def_id)) + PrintCx::with(|cx| { + write!(f, "{}", cx.tcx.item_path_str(self.def_id)) }) } } impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - write!(f, "{}", tcx.item_path_str(self.did)) + PrintCx::with(|cx| { + write!(f, "{}", cx.tcx.item_path_str(self.did)) }) } } @@ -724,7 +712,9 @@ impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, - ty::tls::with(|tcx| tcx.hir().name_by_hir_id(self.var_path.hir_id)), + PrintCx::with(|cx| { + cx.tcx.hir().name_by_hir_id(self.var_path.hir_id) + }), self.closure_expr_id) } } @@ -768,14 +758,12 @@ define_print! { cx.parameterized(f, self.substs, self.def_id, &[]) } debug { - ty::tls::with(|tcx| { - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); + let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = *tcx.lift(&ty::Binder::bind(*self)) - .expect("could not lift for printing") - .with_self_ty(tcx, dummy_self).skip_binder(); - cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) - }) + let trait_ref = *cx.tcx.lift(&ty::Binder::bind(*self)) + .expect("could not lift for printing") + .with_self_ty(cx.tcx, dummy_self).skip_binder(); + cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) } } } @@ -1092,7 +1080,7 @@ impl fmt::Debug for ty::FloatVarValue { for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, tcx.lift(self) + PrintCx::with(|cx| cx.in_binder(f, cx.tcx.lift(self) .expect("could not lift for printing"))) } }*/ @@ -1110,8 +1098,8 @@ define_print_multi! { ] (self, f, cx) { display { - ty::tls::with(|tcx| cx.in_binder(f, tcx, tcx.lift(self) - .expect("could not lift for printing"))) + cx.in_binder(f, cx.tcx.lift(self) + .expect("could not lift for printing")) } } } @@ -1178,12 +1166,10 @@ define_print! { write!(f, ")") } FnDef(def_id, substs) => { - ty::tls::with(|tcx| { - let substs = tcx.lift(&substs) - .expect("could not lift for printing"); - let sig = tcx.fn_sig(def_id).subst(tcx, substs); - print!(f, cx, print(sig), write(" {{")) - })?; + let substs = cx.tcx.lift(&substs) + .expect("could not lift for printing"); + let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); + print!(f, cx, print(sig), write(" {{"))?; cx.parameterized(f, substs, def_id, &[])?; write!(f, "}}") } @@ -1235,71 +1221,69 @@ define_print! { return write!(f, "Opaque({:?}, {:?})", def_id, substs); } - ty::tls::with(|tcx| { - let def_key = tcx.def_key(def_id); - if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - write!(f, "{}", name)?; - let mut substs = substs.iter(); - if let Some(first) = substs.next() { - write!(f, "::<")?; - write!(f, "{}", first)?; - for subst in substs { - write!(f, ", {}", subst)?; - } - write!(f, ">")?; + let def_key = cx.tcx.def_key(def_id); + if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { + write!(f, "{}", name)?; + let mut substs = substs.iter(); + if let Some(first) = substs.next() { + write!(f, "::<")?; + write!(f, "{}", first)?; + for subst in substs { + write!(f, ", {}", subst)?; } - return Ok(()); + write!(f, ">")?; } - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let substs = tcx.lift(&substs) - .expect("could not lift for printing"); - let bounds = tcx.predicates_of(def_id).instantiate(tcx, substs); - - let mut first = true; - let mut is_sized = false; - write!(f, "impl")?; - for predicate in bounds.predicates { - if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { - is_sized = true; - continue; - } - - print!(f, cx, - write("{}", if first { " " } else { "+" }), - print(trait_ref))?; - first = false; + return Ok(()); + } + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let substs = cx.tcx.lift(&substs) + .expect("could not lift for printing"); + let bounds = cx.tcx.predicates_of(def_id).instantiate(cx.tcx, substs); + + let mut first = true; + let mut is_sized = false; + write!(f, "impl")?; + for predicate in bounds.predicates { + if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { + // Don't print +Sized, but rather +?Sized if absent. + if Some(trait_ref.def_id()) == cx.tcx.lang_items().sized_trait() { + is_sized = true; + continue; } + + print!(f, cx, + write("{}", if first { " " } else { "+" }), + print(trait_ref))?; + first = false; } - if !is_sized { - write!(f, "{}?Sized", if first { " " } else { "+" })?; + } + if !is_sized { + write!(f, "{}?Sized", if first { " " } else { "+" })?; } else if first { write!(f, " Sized")?; - } - Ok(()) - }) + } + Ok(()) } Str => write!(f, "str"), - Generator(did, substs, movability) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); - let witness = substs.witness(did, tcx); + Generator(did, substs, movability) => { + let upvar_tys = substs.upvar_tys(did, cx.tcx); + let witness = substs.witness(did, cx.tcx); if movability == hir::GeneratorMovability::Movable { write!(f, "[generator")?; } else { write!(f, "[static generator")?; } - if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { - write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?; + if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { + write!(f, "@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))?; let mut sep = " "; - tcx.with_freevars(hir_id, |freevars| { + cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { print!(f, cx, write("{}{}:", sep, - tcx.hir().name(freevar.var_id())), + cx.tcx.hir().name(freevar.var_id())), print(upvar_ty))?; sep = ", "; } @@ -1319,28 +1303,28 @@ define_print! { } print!(f, cx, write(" "), print(witness), write("]")) - }), + }, GeneratorWitness(types) => { - ty::tls::with(|tcx| cx.in_binder(f, tcx, tcx.lift(&types) - .expect("could not lift for printing"))) + cx.in_binder(f, cx.tcx.lift(&types) + .expect("could not lift for printing")) } - Closure(did, substs) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); + Closure(did, substs) => { + let upvar_tys = substs.upvar_tys(did, cx.tcx); write!(f, "[closure")?; - if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { - if tcx.sess.opts.debugging_opts.span_free_formats { + if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { + if cx.tcx.sess.opts.debugging_opts.span_free_formats { write!(f, "@{:?}", hir_id)?; } else { - write!(f, "@{:?}", tcx.hir().span_by_hir_id(hir_id))?; + write!(f, "@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))?; } let mut sep = " "; - tcx.with_freevars(hir_id, |freevars| { + cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { print!(f, cx, write("{}{}:", sep, - tcx.hir().name(freevar.var_id())), + cx.tcx.hir().name(freevar.var_id())), print(upvar_ty))?; sep = ", "; } @@ -1369,21 +1353,21 @@ define_print! { } write!(f, "]") - }), + }, Array(ty, sz) => { print!(f, cx, write("["), print(ty), write("; "))?; match sz { ty::LazyConst::Unevaluated(_def_id, _substs) => { write!(f, "_")?; } - ty::LazyConst::Evaluated(c) => ty::tls::with(|tcx| { + ty::LazyConst::Evaluated(c) => { match c.val { - ConstValue::Infer(..) => write!(f, "_"), + ConstValue::Infer(..) => write!(f, "_")?, ConstValue::Param(ParamConst { name, .. }) => - write!(f, "{}", name), - _ => write!(f, "{}", c.unwrap_usize(tcx)), + write!(f, "{}", name)?, + _ => write!(f, "{}", c.unwrap_usize(cx.tcx))?, } - })?, + } } write!(f, "]") } @@ -1510,9 +1494,8 @@ define_print! { // FIXME(tschottdorf): use something like // parameterized(f, self.substs, self.item_def_id, &[]) // (which currently ICEs). - let (trait_ref, item_name) = ty::tls::with(|tcx| - (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).ident) - ); + let trait_ref = self.trait_ref(cx.tcx); + let item_name = cx.tcx.associated_item(self.item_def_id).ident; print!(f, cx, print_debug(trait_ref), write("::{}", item_name)) } } @@ -1540,15 +1523,13 @@ define_print! { ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx), ty::Predicate::Projection(ref predicate) => predicate.print(f, cx), ty::Predicate::WellFormed(ty) => print!(f, cx, print(ty), write(" well-formed")), - ty::Predicate::ObjectSafe(trait_def_id) => - ty::tls::with(|tcx| { - write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id)) - }), - ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => - ty::tls::with(|tcx| { - write!(f, "the closure `{}` implements the trait `{}`", - tcx.item_path_str(closure_def_id), kind) - }), + ty::Predicate::ObjectSafe(trait_def_id) => { + write!(f, "the trait `{}` is object-safe", cx.tcx.item_path_str(trait_def_id)) + } + ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { + write!(f, "the closure `{}` implements the trait `{}`", + cx.tcx.item_path_str(closure_def_id), kind) + } ty::Predicate::ConstEvaluatable(def_id, substs) => { write!(f, "the constant `")?; cx.parameterized(f, substs, def_id, &[])?; From 01fa283d6feac5838317d0b16e4dda8dff3e4826 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 19:14:30 +0200 Subject: [PATCH 084/157] rustc: remove fmt::{Debug,Display} from ty::TyKind. --- src/librustc/middle/mem_categorization.rs | 17 ++++++++------ src/librustc/traits/error_reporting.rs | 9 ++++---- src/librustc/ty/relate.rs | 6 ++--- src/librustc/ty/sty.rs | 7 +++--- src/librustc/util/ppaux.rs | 14 +++-------- src/librustc_codegen_llvm/intrinsic.rs | 23 +++++++++---------- src/librustc_codegen_ssa/mir/constant.rs | 2 +- src/librustc_codegen_ssa/traits/type_.rs | 2 +- .../borrow_check/error_reporting.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 5 ++-- src/librustc_mir/hair/pattern/mod.rs | 10 ++++---- src/librustc_mir/hair/util.rs | 10 +++++--- src/librustc_mir/interpret/cast.rs | 6 ++--- src/librustc_mir/interpret/operator.rs | 2 +- src/librustc_mir/interpret/place.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_typeck/astconv.rs | 4 +++- src/librustc_typeck/check/_match.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 6 ++--- src/librustc_typeck/check/upvar.rs | 7 +++--- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/check/writeback.rs | 2 +- 22 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index a3e8598194e79..ea1c9d8141611 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -786,7 +786,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk // FnOnce | copied | upvar -> &'up bk - let kind = match self.node_ty(fn_hir_id)?.sty { + let ty = self.node_ty(fn_hir_id)?; + let kind = match ty.sty { ty::Generator(..) => ty::ClosureKind::FnOnce, ty::Closure(closure_def_id, closure_substs) => { match self.infcx { @@ -803,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { .closure_kind(closure_def_id, self.tcx.global_tcx()), } } - ref t => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", t), + _ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty), }; let closure_expr_def_id = self.tcx.hir().local_def_id(fn_node_id); @@ -1064,7 +1065,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let bk = ty::BorrowKind::from_mutbl(mutbl); BorrowedPtr(bk, r) } - ref ty => bug!("unexpected type in cat_deref: {:?}", ty) + _ => bug!("unexpected type in cat_deref: {:?}", base_cmt.ty) }; let ret = cmt_ { hir_id: node.hir_id(), @@ -1279,11 +1280,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()) } Def::StructCtor(_, CtorKind::Fn) | Def::SelfCtor(..) => { - match self.pat_ty_unadjusted(&pat)?.sty { + let ty = self.pat_ty_unadjusted(&pat)?; + match ty.sty { ty::Adt(adt_def, _) => { (cmt, adt_def.non_enum_variant().fields.len()) } - ref ty => { + _ => { span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty); } @@ -1334,9 +1336,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::Tuple(ref subpats, ddpos) => { // (p1, ..., pN) - let expected_len = match self.pat_ty_unadjusted(&pat)?.sty { + let ty = self.pat_ty_unadjusted(&pat)?; + let expected_len = match ty.sty { ty::Tuple(ref tys) => tys.len(), - ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), + _ => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index c7674ae7a28a2..0dd076481c887 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -854,10 +854,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => vec![ArgKind::empty()], }; - let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { + let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); + let expected = match expected_ty.sty { ty::Tuple(ref tys) => tys.iter() .map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(), - ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())], + _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], }; if found.len() == expected.len() { @@ -1686,10 +1687,10 @@ impl ArgKind { ty::Tuple(ref tys) => ArgKind::Tuple( span, tys.iter() - .map(|ty| ("_".to_owned(), ty.sty.to_string())) + .map(|ty| ("_".to_owned(), ty.to_string())) .collect::>() ), - _ => ArgKind::Arg("_".to_owned(), t.sty.to_string()), + _ => ArgKind::Arg("_".to_owned(), t.to_string()), } } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 3a31801b3be39..b245d90379996 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -351,10 +351,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { let tcx = relation.tcx(); - let a_sty = &a.sty; - let b_sty = &b.sty; - debug!("super_relate_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty); - match (a_sty, b_sty) { + debug!("super_relate_tys: a={:?} b={:?}", a, b); + match (&a.sty, &b.sty) { (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 39728cc8cd5cb..20acbb5b9c712 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -84,7 +84,7 @@ impl BoundRegion { /// N.B., if you change this, you'll probably want to change the corresponding /// AST structure in `libsyntax/ast.rs` as well. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] pub enum TyKind<'tcx> { /// The primitive boolean type. Written as `bool`. @@ -383,9 +383,10 @@ impl<'tcx> ClosureSubsts<'tcx> { /// /// If you have an inference context, use `infcx.closure_sig()`. pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> { - match self.closure_sig_ty(def_id, tcx).sty { + let ty = self.closure_sig_ty(def_id, tcx); + match ty.sty { ty::FnPtr(sig) => sig, - ref t => bug!("closure_sig_ty is not a fn-ptr: {:?}", t), + _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty), } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ff66df4e4a3f6..7f41947fbb929 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1124,9 +1124,9 @@ define_print! { } define_print! { - ('tcx) ty::TyKind<'tcx>, (self, f, cx) { + ('tcx) ty::TyS<'tcx>, (self, f, cx) { display { - match *self { + match self.sty { Bool => write!(f, "bool"), Char => write!(f, "char"), Int(t) => write!(f, "{}", t.ty_to_string()), @@ -1376,16 +1376,8 @@ define_print! { } } } - } -} - -define_print! { - ('tcx) ty::TyS<'tcx>, (self, f, cx) { - display { - self.sty.print(f, cx) - } debug { - self.sty.print_display(f, cx) + self.print_display(f, cx) } } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 3268af396a2f4..12edb3a090712 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -513,8 +513,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { }, "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { - let sty = &arg_tys[0].sty; - match float_type_width(sty) { + match float_type_width(arg_tys[0]) { Some(_width) => match name { "fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()), @@ -528,7 +527,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { span_invalid_monomorphization_error( tcx.sess, span, &format!("invalid monomorphization of `{}` intrinsic: \ - expected basic float type, found `{}`", name, sty)); + expected basic float type, found `{}`", name, arg_tys[0])); return; } } @@ -1473,8 +1472,8 @@ fn generic_simd_intrinsic( require!(false, "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*_ {}`", - arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx).sty, in_elem); + arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, + arg_tys[1].simd_type(tcx), in_elem); unreachable!(); } }; @@ -1488,7 +1487,7 @@ fn generic_simd_intrinsic( _ => { require!(false, "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx).sty, arg_tys[2]); + arg_tys[2].simd_type(tcx), arg_tys[2]); } } @@ -1573,8 +1572,8 @@ fn generic_simd_intrinsic( require!(false, "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*mut {}`", - arg_tys[1].simd_type(tcx).sty, arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx).sty, in_elem); + arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, + arg_tys[1].simd_type(tcx), in_elem); unreachable!(); } }; @@ -1588,7 +1587,7 @@ fn generic_simd_intrinsic( _ => { require!(false, "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx).sty, arg_tys[2]); + arg_tys[2].simd_type(tcx), arg_tys[2]); } } @@ -1954,10 +1953,10 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo } } -// Returns the width of a float TypeVariant +// Returns the width of a float Ty // Returns None if the type is not a float -fn float_type_width<'tcx>(sty: &ty::TyKind<'tcx>) -> Option { - match *sty { +fn float_type_width(ty: Ty) -> Option { + match ty.sty { ty::Float(t) => Some(t.bit_width() as u64), _ => None, } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 349c9132842b8..2bb68dc687ca9 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let field_ty = c.ty.builtin_index().unwrap(); let fields = match c.ty.sty { ty::Array(_, n) => n.unwrap_usize(bx.tcx()), - ref other => bug!("invalid simd shuffle type: {}", other), + _ => bug!("invalid simd shuffle type: {}", c.ty), }; let values: Vec<_> = (0..fields).map(|field| { let field = const_field( diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 7c5e615f22452..fe00276a55a45 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -148,7 +148,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), + _ => bug!("unexpected unsized tail: {:?}", tail), } } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index fe07cc0698a0a..aa3750946d366 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1799,7 +1799,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // (https://github.com/rust-lang/rfcs/pull/1546) bug!( "End-user description not implemented for field access on `{:?}`", - ty.sty + ty ); } } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 7749b3a5ca49e..c8c6d73d4536a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -955,7 +955,8 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_provided_types = cx.tables.user_provided_types(); let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty); debug!("convert_path_expr: user_provided_type={:?}", user_provided_type); - match cx.tables().node_type(expr.hir_id).sty { + let ty = cx.tables().node_type(expr.hir_id); + match ty.sty { // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. ty::Adt(adt_def, substs) => { @@ -968,7 +969,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, base: None, } } - ref sty => bug!("unexpected sty: {:?}", sty), + _ => bug!("unexpected ty: {:?}", ty), } } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 67d40197290f1..8aa4fdedc18e2 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -529,11 +529,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) }; } - ref sty => + _ => span_bug!( pat.span, "unexpanded type for vector pattern: {:?}", - sty), + ty), } } @@ -554,7 +554,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE (#50577) return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) }; } - ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty), + _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty), } } @@ -608,7 +608,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", - ty.sty), + ty), }; let variant_def = adt_def.variant_of_def(def); @@ -744,7 +744,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Error => { // Avoid ICE (#50585) return PatternKind::Wild; } - _ => bug!("inappropriate type for def: {:?}", ty.sty), + _ => bug!("inappropriate type for def: {:?}", ty), }; PatternKind::Variant { adt_def, diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index 4618cd42686fa..c9dae6990795b 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -16,7 +16,8 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { let user_provided_types = self.tables().user_provided_types(); let mut user_ty = *user_provided_types.get(hir_id)?; debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty); - match &self.tables().node_type(hir_id).sty { + let ty = self.tables().node_type(hir_id); + match ty.sty { ty::Adt(adt_def, ..) => { if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value { *did = adt_def.did; @@ -24,8 +25,11 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> { Some(user_ty) } ty::FnDef(..) => Some(user_ty), - sty => - bug!("sty: {:?} should not have user provided type {:?} recorded ", sty, user_ty), + _ => bug!( + "ty: {:?} should not have user provided type {:?} recorded ", + ty, + user_ty + ), } } } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 73c73cc23dcf0..7543dd678d032 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -90,7 +90,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag(); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } - ref other => bug!("reify fn pointer on {:?}", other), + _ => bug!("reify fn pointer on {:?}", src.layout.ty), } } @@ -101,7 +101,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // No change to value self.write_immediate(*src, dest)?; } - ref other => bug!("fn to unsafe fn cast on {:?}", other), + _ => bug!("fn to unsafe fn cast on {:?}", dest.layout.ty), } } @@ -120,7 +120,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into()); self.write_immediate(val, dest)?; } - ref other => bug!("closure fn pointer on {:?}", other), + _ => bug!("closure fn pointer on {:?}", src.layout.ty), } } } diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b3b9c742d6c28..944e393d296fc 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -336,7 +336,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let layout = val.layout; let val = val.to_scalar()?; - trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty.sty); + trace!("Running unary op {:?}: {:?} ({:?})", un_op, val, layout.ty); match layout.ty.sty { ty::Bool => { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 4df274bc9df97..755bbd96b02f9 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -354,7 +354,7 @@ where ty::Ref(_, _, mutbl) => Some(mutbl), ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable), ty::RawPtr(_) => None, - _ => bug!("Unexpected pointer type {}", val.layout.ty.sty), + _ => bug!("Unexpected pointer type {}", val.layout.ty), }; place.mplace.ptr = M::tag_dereference(self, place, mutbl)?; Ok(place) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 1e245faddf04c..bfdf34f3e37e4 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -836,7 +836,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match tail.sty { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), + _ => bug!("unexpected unsized tail: {:?}", tail), } }; if type_has_metadata(inner_source) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 89ec92a652160..fd09ce7f689b5 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -959,7 +959,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`). fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF); + if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF { + bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref); + } ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref) } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 1a3ade7f8baf6..342a214e0cc22 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // See the examples in `run-pass/match-defbm*.rs`. let mut pat_adjustments = vec![]; while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty { - debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty); + debug!("inspecting {:?}", exp_ty); debug!("current discriminant is Ref, inserting implicit deref"); // Preserve the reference type. We'll need it later during HAIR lowering. @@ -894,7 +894,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); subpats.len() < variant.fields.len() && ddpos.is_some() { let substs = match pat_ty.sty { ty::Adt(_, substs) => substs, - ref ty => bug!("unexpected pattern type {:?}", ty), + _ => bug!("unexpected pattern type {:?}", pat_ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 28c79ce0c74e8..c40bdae0762a9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3885,7 +3885,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(adt, substs) => { Some((adt.variant_of_def(def), adt.did, substs)) } - _ => bug!("unexpected type: {:?}", ty.sty) + _ => bug!("unexpected type: {:?}", ty) } } Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | @@ -5226,8 +5226,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.node); let sp = ty.span; let ty = AstConv::ast_ty_to_ty(self, ty); - debug!("suggest_missing_return_type: return type sty {:?}", ty.sty); - debug!("suggest_missing_return_type: expected type sty {:?}", ty.sty); + debug!("suggest_missing_return_type: return type {:?}", ty); + debug!("suggest_missing_return_type: expected type {:?}", ty); if ty.sty == expected.sty { err.span_label(sp, format!("expected `{}` because of return type", expected)); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 3e6e6576b63ba..a76dfdd69ba97 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -93,19 +93,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); // Extract the type of the closure. - let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty { + let ty = self.node_ty(closure_hir_id); + let (closure_def_id, substs) = match ty.sty { ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)), ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)), ty::Error => { // #51714: skip analysis when we have already encountered type errors return; } - ref t => { + _ => { span_bug!( span, "type of closure expr {:?} is not a closure {:?}", closure_hir_id, - t + ty ); } }; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index fde940eb2c111..92c44e24998e5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -618,7 +618,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( span: Span, ty: Ty<'tcx>, ) -> Vec> { - trace!("check_existential_types: {:?}, {:?}", ty, ty.sty); + trace!("check_existential_types: {:?}", ty); let mut substituted_predicates = Vec::new(); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.tcx, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index d001545d1d915..4a3d4f31a2473 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -472,7 +472,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { instantiated_ty.fold_with(&mut BottomUpFolder { tcx: self.tcx().global_tcx(), fldop: |ty| { - trace!("checking type {:?}: {:#?}", ty, ty.sty); + trace!("checking type {:?}", ty); // find a type parameter if let ty::Param(..) = ty.sty { // look it up in the substitution list From 3bad9f7b3d09a49277d5861733706f03dde1e7c5 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 20:10:47 +0200 Subject: [PATCH 085/157] rustc: implement fmt::{Debug,Display} on Ty instead of TyS. --- src/librustc/util/ppaux.rs | 2 +- src/librustc_mir/util/graphviz.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7f41947fbb929..6d09f72a76b04 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1124,7 +1124,7 @@ define_print! { } define_print! { - ('tcx) ty::TyS<'tcx>, (self, f, cx) { + ('tcx) ty::Ty<'tcx>, (self, f, cx) { display { match self.sty { Bool => write!(f, "bool"), diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 61b1a5a850d28..41e16684b8ac5 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -141,7 +141,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, )?; } - write!(w, ") -> {}", escape(mir.return_ty()))?; + write!(w, ") -> {}", escape(&mir.return_ty()))?; write!(w, r#"
"#)?; for local in mir.vars_and_temps_iter() { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 52514a3ca97d6..c7e63a83b1561 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -134,7 +134,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V> ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | ty::Generator(def_id, ..) => { - if self.def_id_visitor.visit_def_id(def_id, "type", ty) { + if self.def_id_visitor.visit_def_id(def_id, "type", &ty) { return true; } if self.def_id_visitor.shallow() { From eb525b0916e0b228000a6d3ddfb57979cd5342f6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 17:40:23 +0200 Subject: [PATCH 086/157] rustc: tie the 'tcx between Print and PrintCx in ty::print. --- .../infer/outlives/free_region_map.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/instance.rs | 2 +- src/librustc/ty/mod.rs | 4 +- src/librustc/ty/print.rs | 16 +- src/librustc/ty/structural_impls.rs | 32 ++++ src/librustc/ty/sty.rs | 2 +- src/librustc/ty/subst.rs | 6 +- src/librustc/util/ppaux.rs | 139 ++++++++---------- src/librustc_codegen_llvm/intrinsic.rs | 4 +- 10 files changed, 115 insertions(+), 94 deletions(-) diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index 78353e52ad462..5349e990a7761 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -91,7 +91,7 @@ impl_stable_hash_for!(struct FreeRegionMap<'tcx> { impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { - self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx)) + self.relation.maybe_map(|&fr| tcx.lift(&fr)) .map(|relation| FreeRegionMap { relation }) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index b04bb5b3d0171..bff07de5bcf33 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2405,7 +2405,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, substs, variant_def.did, &[])?; + ppaux::parameterized(fmt, variant_def.did, substs)?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index e0b7bbc68e25e..0a49dea7ec1bc 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -175,7 +175,7 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ppaux::parameterized(f, self.substs, self.def_id(), &[])?; + ppaux::parameterized(f, self.def_id(), self.substs)?; match self.def { InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 23fa81f77df28..dbccd60f86b63 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1001,7 +1001,7 @@ impl<'a, 'gcx, 'tcx> Generics { } /// Bounds on generics. -#[derive(Clone, Default, HashStable)] +#[derive(Clone, Default, Debug, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: Vec<(Predicate<'tcx>, Span)>, @@ -1506,7 +1506,7 @@ impl<'tcx> Predicate<'tcx> { /// `[[], [U:Bar]]`. Now if there were some particular reference /// like `Foo`, then the `InstantiatedPredicates` would be `[[], /// [usize:Bar]]`. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct InstantiatedPredicates<'tcx> { pub predicates: Vec>, } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index fb296519d4997..a9fffa2ee87b1 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -56,32 +56,36 @@ impl PrintCx<'a, 'gcx, 'tcx> { } pub trait Print<'tcx> { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print(&mut result, cx); result } - fn print_display(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print_display( + &self, + f: &mut F, + cx: &mut PrintCx<'_, '_, 'tcx>, + ) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = false; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print_display(&mut result, cx); result } - fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print_debug(&mut result, cx); result diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f9eb336a4a3e2..a19eb1d9545a2 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -48,7 +48,10 @@ CloneTypeFoldableAndLiftImpls! { // really meant to be folded. In general, we can only fold a fully // general `Region`. crate::ty::BoundRegion, + crate::ty::Placeholder, crate::ty::ClosureKind, + crate::ty::FreeRegion, + crate::ty::InferTy, crate::ty::IntVarValue, crate::ty::ParamConst, crate::ty::ParamTy, @@ -480,6 +483,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { } } +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> { + type Lifted = ty::TypeAndMut<'tcx>; + ty, mutbl + } +} + BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> { type Lifted = ty::Instance<'tcx>; @@ -494,6 +504,28 @@ BraceStructLiftImpl! { } } +// FIXME(eddyb) this is like what some of the macros above generate, +// except that macros *also* generate a foldable impl, which we don't +// want (with it we'd risk bypassing `fold_region` / `fold_const`). +impl<'tcx> Lift<'tcx> for ty::RegionKind { + type Lifted = ty::RegionKind; + fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + Some(self.clone()) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> { + type Lifted = ty::LazyConst<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + match self { + ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)), + ty::LazyConst::Unevaluated(def_id, substs) => { + Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?)) + } + } + } +} + BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> { type Lifted = ty::Const<'tcx>; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 20acbb5b9c712..0e4b43155d9c2 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -616,7 +616,7 @@ impl<'tcx> List> { #[inline] pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a { + impl Iterator> + Clone + 'a { self.iter().filter_map(|predicate| { match *predicate { ExistentialPredicate::Projection(p) => Some(p), diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 38be19a71c48c..85a05bb9f5585 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -140,9 +140,9 @@ impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option { match self.unpack() { - UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()), - UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()), - UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()), + UnpackedKind::Lifetime(lt) => tcx.lift(<).map(|lt| lt.into()), + UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()), + UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()), } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6d09f72a76b04..b56ce0665e9e9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -14,6 +14,7 @@ use crate::mir::interpret::ConstValue; use std::cell::Cell; use std::fmt; +use std::iter; use std::usize; use rustc_target::spec::abi::Abi; @@ -182,7 +183,9 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|mut cx| $with(self, f, &mut cx)) + PrintCx::with(|mut cx| { + $with(&cx.tcx.lift(self).expect("could not lift for printing"), f, &mut cx) + }) } }; } @@ -215,7 +218,7 @@ macro_rules! gen_print_impl { fn print( &$self, $f: &mut F, - $cx: &mut PrintCx<'_, '_, '_>, + $cx: &mut PrintCx<'_, '_, 'tcx>, ) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -227,7 +230,7 @@ macro_rules! gen_print_impl { fn print( &$self, $f: &mut F, - $cx: &mut PrintCx<'_, '_, '_>, + $cx: &mut PrintCx<'_, '_, 'tcx>, ) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -285,9 +288,9 @@ macro_rules! print { impl PrintCx<'a, 'gcx, 'tcx> { fn fn_sig(&mut self, f: &mut F, - inputs: &[Ty<'_>], + inputs: &[Ty<'tcx>], c_variadic: bool, - output: Ty<'_>) + output: Ty<'tcx>) -> fmt::Result { write!(f, "(")?; let mut inputs = inputs.iter(); @@ -308,12 +311,13 @@ impl PrintCx<'a, 'gcx, 'tcx> { Ok(()) } - fn parameterized(&mut self, - f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { + fn parameterized( + &mut self, + f: &mut F, + did: DefId, + substs: SubstsRef<'tcx>, + projections: impl Iterator> + Clone, + ) -> fmt::Result { let key = self.tcx.def_key(did); let verbose = self.is_verbose; @@ -411,7 +415,6 @@ impl PrintCx<'a, 'gcx, 'tcx> { *has_default.unwrap_or(&false) }; if has_default { - let substs = self.tcx.lift(&substs).expect("could not lift for printing"); let types = substs.types().rev().skip(child_types); for ((def_id, has_default), actual) in type_params.zip(types) { if !has_default { @@ -428,10 +431,12 @@ impl PrintCx<'a, 'gcx, 'tcx> { print!(f, self, write("{}", self.tcx.item_path_str(path_def_id)))?; let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(path_def_id); - if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { - let projection_ty = projections[0].ty; + if !verbose && fn_trait_kind.is_some() { if let Tuple(ref args) = substs.type_at(1).sty { - return self.fn_sig(f, args, false, projection_ty); + let mut projections = projections.clone(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + return self.fn_sig(f, args, false, proj.ty); + } } } @@ -490,7 +495,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { start_or_continue(f, "<", ", ")?; print!(f, self, write("{}=", - self.tcx.associated_item(projection.projection_ty.item_def_id).ident), + self.tcx.associated_item(projection.item_def_id).ident), print_display(projection.ty))?; } @@ -530,7 +535,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { Ok(()) } - fn in_binder(&mut self, f: &mut F, value: ty::Binder) -> fmt::Result + fn in_binder(&mut self, f: &mut F, value: &ty::Binder) -> fmt::Result where T: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write { fn name_by_region_index(index: usize) -> InternedString { @@ -547,7 +552,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { // the output. We'll probably want to tweak this over time to // decide just how much information to give. if self.binder_depth == 0 { - self.prepare_late_bound_region_info(&value); + self.prepare_late_bound_region_info(value); } let mut empty = true; @@ -562,7 +567,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { let old_region_index = self.region_index; let mut region_index = old_region_index; - let new_value = self.tcx.replace_late_bound_regions(&value, |br| { + let new_value = self.tcx.replace_late_bound_regions(value, |br| { let _ = start_or_continue(f, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { @@ -604,16 +609,15 @@ impl PrintCx<'a, 'gcx, 'tcx> { } } -pub fn parameterized(f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { - PrintCx::with(|mut cx| cx.parameterized(f, substs, did, projections)) +pub fn parameterized(f: &mut F, did: DefId, substs: SubstsRef<'_>) -> fmt::Result { + PrintCx::with(|mut cx| { + let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); + cx.parameterized(f, did, substs, iter::empty()) + }) } impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { (*self).print(f, cx) } } @@ -628,16 +632,13 @@ define_print! { let mut first = true; if let Some(principal) = self.principal() { - let principal = cx.tcx - .lift(&principal) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - cx.tcx.lift(&p) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; + let principal = principal.with_self_ty(cx.tcx, dummy_self); + cx.parameterized( + f, + principal.def_id, + principal.substs, + self.projection_bounds(), + )?; first = false; } @@ -755,15 +756,15 @@ define_print! { define_print! { ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) { display { - cx.parameterized(f, self.substs, self.def_id, &[]) - } - debug { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = *cx.tcx.lift(&ty::Binder::bind(*self)) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self).skip_binder(); - cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) + let trait_ref = *ty::Binder::bind(*self) + .with_self_ty(cx.tcx, dummy_self) + .skip_binder(); + cx.parameterized(f, trait_ref.def_id, trait_ref.substs, iter::empty()) + } + debug { + self.print_display(f, cx) } } } @@ -957,22 +958,6 @@ define_print! { } } -define_print! { - ('tcx) ty::GenericPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "GenericPredicates({:?})", self.predicates) - } - } -} - -define_print! { - ('tcx) ty::InstantiatedPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "InstantiatedPredicates({:?})", self.predicates) - } - } -} - define_print! { ('tcx) ty::FnSig<'tcx>, (self, f, cx) { display { @@ -1098,8 +1083,7 @@ define_print_multi! { ] (self, f, cx) { display { - cx.in_binder(f, cx.tcx.lift(self) - .expect("could not lift for printing")) + cx.in_binder(f, self) } } } @@ -1107,7 +1091,7 @@ define_print_multi! { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, f, cx) { display { - cx.parameterized(f, self.substs, self.def_id, &[]) + cx.parameterized(f, self.def_id, self.substs, iter::empty()) } debug { // when printing out the debug representation, we don't need @@ -1117,7 +1101,7 @@ define_print! { write("<"), print(self.self_ty()), write(" as "))?; - cx.parameterized(f, self.substs, self.def_id, &[])?; + cx.parameterized(f, self.def_id, self.substs, iter::empty())?; write!(f, ">") } } @@ -1166,11 +1150,9 @@ define_print! { write!(f, ")") } FnDef(def_id, substs) => { - let substs = cx.tcx.lift(&substs) - .expect("could not lift for printing"); let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); print!(f, cx, print(sig), write(" {{"))?; - cx.parameterized(f, substs, def_id, &[])?; + cx.parameterized(f, def_id, substs, iter::empty())?; write!(f, "}}") } FnPtr(ref bare_fn) => { @@ -1192,7 +1174,7 @@ define_print! { ty::BoundTyKind::Param(p) => write!(f, "{}", p), } } - Adt(def, substs) => cx.parameterized(f, substs, def.did, &[]), + Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()), Dynamic(data, r) => { let r = r.print_to_string(cx); if !r.is_empty() { @@ -1206,7 +1188,9 @@ define_print! { Ok(()) } } - Foreign(def_id) => parameterized(f, subst::InternalSubsts::empty(), def_id, &[]), + Foreign(def_id) => { + cx.parameterized(f, def_id, subst::InternalSubsts::empty(), iter::empty()) + } Projection(ref data) => data.print(f, cx), UnnormalizedProjection(ref data) => { write!(f, "Unnormalized(")?; @@ -1237,8 +1221,6 @@ define_print! { } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let substs = cx.tcx.lift(&substs) - .expect("could not lift for printing"); let bounds = cx.tcx.predicates_of(def_id).instantiate(cx.tcx, substs); let mut first = true; @@ -1305,8 +1287,7 @@ define_print! { print!(f, cx, write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { - cx.in_binder(f, cx.tcx.lift(&types) - .expect("could not lift for printing")) + cx.in_binder(f, &types) } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); @@ -1347,8 +1328,8 @@ define_print! { write!( f, " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, tcx), - substs.closure_sig_ty(did, tcx), + substs.closure_kind_ty(did, cx.tcx), + substs.closure_sig_ty(did, cx.tcx), )?; } @@ -1435,8 +1416,12 @@ define_print! { } } -define_print! { - ('tcx, T: Print<'tcx> + fmt::Debug, U: Print<'tcx> + fmt::Debug) ty::OutlivesPredicate, +// Similar problem to `Binder`, can't define a generic impl. +define_print_multi! { + [ + ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>>, + ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>> + ] (self, f, cx) { display { print!(f, cx, print(self.0), write(" : "), print(self.1)) @@ -1524,7 +1509,7 @@ define_print! { } ty::Predicate::ConstEvaluatable(def_id, substs) => { write!(f, "the constant `")?; - cx.parameterized(f, substs, def_id, &[])?; + cx.parameterized(f, def_id, substs, iter::empty())?; write!(f, "` can be evaluated") } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 12edb3a090712..ceb08f943678b 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1903,7 +1903,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, return_error!( "expected element type `{}` of vector type `{}` \ to be a signed or unsigned integer type", - arg_tys[0].simd_type(tcx).sty, arg_tys[0] + arg_tys[0].simd_type(tcx), arg_tys[0] ); } }; @@ -1955,7 +1955,7 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo // Returns the width of a float Ty // Returns None if the type is not a float -fn float_type_width(ty: Ty) -> Option { +fn float_type_width(ty: Ty<'_>) -> Option { match ty.sty { ty::Float(t) => Some(t.bit_width() as u64), _ => None, From 939c69c71f8583e37f536a0c6da75c31bc878383 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 8 Dec 2018 01:13:23 +0200 Subject: [PATCH 087/157] rustc: use define_print! to implement fmt::{Display,Debug} for Kind. --- src/librustc/ty/subst.rs | 19 ------------------- src/librustc/util/ppaux.rs | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 85a05bb9f5585..973f7f15f84ca 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -13,7 +13,6 @@ use rustc_macros::HashStable; use core::intrinsics; use std::cmp::Ordering; -use std::fmt; use std::marker::PhantomData; use std::mem; use std::num::NonZeroUsize; @@ -115,26 +114,8 @@ impl<'tcx> Kind<'tcx> { } } -impl<'tcx> fmt::Debug for Kind<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { - UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt), - UnpackedKind::Type(ty) => write!(f, "{:?}", ty), UnpackedKind::Const(ct) => write!(f, "{:?}", ct), - } - } -} - -impl<'tcx> fmt::Display for Kind<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.unpack() { - UnpackedKind::Lifetime(lt) => write!(f, "{}", lt), - UnpackedKind::Type(ty) => write!(f, "{}", ty), UnpackedKind::Const(ct) => write!(f, "{}", ct), - } - } -} - impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { type Lifted = Kind<'tcx>; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index b56ce0665e9e9..c2b2cf4e62f9a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,7 +1,7 @@ use crate::hir::def_id::DefId; use crate::hir::map::definitions::DefPathData; use crate::middle::region; -use crate::ty::subst::{self, Subst, SubstsRef}; +use crate::ty::subst::{self, Kind, Subst, SubstsRef, UnpackedKind}; use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use crate::ty::{Bool, Char, Adt}; use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; @@ -1535,3 +1535,20 @@ define_print! { } } } + +define_print! { + ('tcx) Kind<'tcx>, (self, f, cx) { + display { + match self.unpack() { + UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), + UnpackedKind::Type(ty) => print!(f, cx, print(ty)), + } + } + debug { + match self.unpack() { + UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), + UnpackedKind::Type(ty) => print!(f, cx, print(ty)), + } + } + } +} From fbbc7e915d362d6e0705197c884fce23246acd1d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 8 Dec 2018 11:26:34 +0200 Subject: [PATCH 088/157] rustc: rewrite PrintCx::parameterized to be much simpler and more general. --- src/librustc/ty/sty.rs | 2 +- src/librustc/ty/subst.rs | 2 - src/librustc/util/ppaux.rs | 329 ++++++++++++++----------------------- 3 files changed, 124 insertions(+), 209 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 0e4b43155d9c2..20acbb5b9c712 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -616,7 +616,7 @@ impl<'tcx> List> { #[inline] pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + Clone + 'a { + impl Iterator> + 'a { self.iter().filter_map(|predicate| { match *predicate { ExistentialPredicate::Projection(p) => Some(p), diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 973f7f15f84ca..8c67cdf62b62f 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -114,8 +114,6 @@ impl<'tcx> Kind<'tcx> { } } - UnpackedKind::Const(ct) => write!(f, "{:?}", ct), - UnpackedKind::Const(ct) => write!(f, "{}", ct), impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { type Lifted = Kind<'tcx>; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c2b2cf4e62f9a..8dfa924c1dfc9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -8,7 +8,7 @@ use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; -use crate::ty::{self, Ty, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst}; +use crate::ty::{self, ParamConst, Ty, TypeFoldable}; use crate::ty::print::{PrintCx, Print}; use crate::mir::interpret::ConstValue; @@ -314,225 +314,130 @@ impl PrintCx<'a, 'gcx, 'tcx> { fn parameterized( &mut self, f: &mut F, - did: DefId, + mut def_id: DefId, substs: SubstsRef<'tcx>, - projections: impl Iterator> + Clone, + projections: impl Iterator>, ) -> fmt::Result { - let key = self.tcx.def_key(did); - - let verbose = self.is_verbose; - let mut num_supplied_defaults = 0; - let has_self; - let mut own_counts: GenericParamCount = Default::default(); - let mut is_value_path = false; - let mut item_name = Some(key.disambiguated_data.data.as_interned_str()); - let mut path_def_id = did; - { - // Unfortunately, some kinds of items (e.g., closures) don't have - // generics. So walk back up the find the closest parent that DOES - // have them. - let mut item_def_id = did; - loop { - let key = self.tcx.def_key(item_def_id); - match key.disambiguated_data.data { - DefPathData::AssocTypeInTrait(_) | - DefPathData::AssocTypeInImpl(_) | - DefPathData::AssocExistentialInImpl(_) | - DefPathData::Trait(_) | - DefPathData::TraitAlias(_) | - DefPathData::Impl | - DefPathData::TypeNs(_) => { - break; - } - DefPathData::ValueNs(_) | - DefPathData::EnumVariant(_) => { - is_value_path = true; - break; - } - DefPathData::CrateRoot | - DefPathData::Misc | - DefPathData::Module(_) | - DefPathData::MacroDef(_) | - DefPathData::ClosureExpr | - DefPathData::TypeParam(_) | - DefPathData::LifetimeParam(_) | - DefPathData::ConstParam(_) | - DefPathData::Field(_) | - DefPathData::StructCtor | - DefPathData::AnonConst | - DefPathData::ImplTrait | - DefPathData::GlobalMetaData(_) => { - // if we're making a symbol for something, there ought - // to be a value or type-def or something in there - // *somewhere* - item_def_id.index = key.parent.unwrap_or_else(|| { - bug!("finding type for {:?}, encountered def-id {:?} with no \ - parent", did, item_def_id); - }); - } - } + let mut key = self.tcx.def_key(def_id); + let is_value_ns = match key.disambiguated_data.data { + DefPathData::ValueNs(_) | + DefPathData::EnumVariant(_) => true, + + // Skip `StructCtor` so that `Struct::` will be printed, + // instead of the less pretty `Struct::{{constructor}}`. + DefPathData::StructCtor => { + def_id.index = key.parent.unwrap(); + key = self.tcx.def_key(def_id); + true } - let mut generics = self.tcx.generics_of(item_def_id); - let child_own_counts = generics.own_counts(); - has_self = generics.has_self; - - let mut child_types = 0; - if let Some(def_id) = generics.parent { - // Methods. - assert!(is_value_path); - child_types = child_own_counts.types; - generics = self.tcx.generics_of(def_id); - own_counts = generics.own_counts(); - - if has_self { - print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; - } - path_def_id = def_id; - } else { - item_name = None; - - if is_value_path { - // Functions. - assert_eq!(has_self, false); - } else { - // Types and traits. - own_counts = child_own_counts; - } - } + _ => false, + }; - if !verbose { - let mut type_params = - generics.params.iter().rev().filter_map(|param| match param.kind { - GenericParamDefKind::Lifetime => None, - GenericParamDefKind::Type { has_default, .. } => { - Some((param.def_id, has_default)) - } - GenericParamDefKind::Const => None, // FIXME(const_generics:defaults) - }).peekable(); - let has_default = { - let has_default = type_params.peek().map(|(_, has_default)| has_default); - *has_default.unwrap_or(&false) - }; - if has_default { - let types = substs.types().rev().skip(child_types); - for ((def_id, has_default), actual) in type_params.zip(types) { - if !has_default { - break; - } - if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { - break; - } - num_supplied_defaults += 1; - } - } + let generics = self.tcx.generics_of(def_id); + + if let Some(parent_def_id) = generics.parent { + assert_eq!(parent_def_id, DefId { index: key.parent.unwrap(), ..def_id }); + + let parent_generics = self.tcx.generics_of(parent_def_id); + let parent_has_own_self = + parent_generics.has_self && parent_generics.parent_count == 0; + if parent_has_own_self { + print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; } - } - print!(f, self, write("{}", self.tcx.item_path_str(path_def_id)))?; - let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(path_def_id); - - if !verbose && fn_trait_kind.is_some() { - if let Tuple(ref args) = substs.type_at(1).sty { - let mut projections = projections.clone(); - if let (Some(proj), None) = (projections.next(), projections.next()) { - return self.fn_sig(f, args, false, proj.ty); - } + self.parameterized(f, parent_def_id, substs, iter::empty())?; + if parent_has_own_self { + write!(f, ">")?; } + + write!(f, "::{}", key.disambiguated_data.data.as_interned_str())?; + } else { + print!(f, self, write("{}", self.tcx.item_path_str(def_id)))?; } - let empty = Cell::new(true); - let start_or_continue = |f: &mut F, start: &str, cont: &str| { - if empty.get() { - empty.set(false); + let mut empty = true; + let mut start_or_continue = |f: &mut F, start: &str, cont: &str| { + if empty { + empty = false; write!(f, "{}", start) } else { write!(f, "{}", cont) } }; - let print_regions = |f: &mut F, start: &str, skip, count| { - // Don't print any regions if they're all erased. - let regions = || substs.regions().skip(skip).take(count); - if regions().all(|r: ty::Region<'_>| *r == ty::ReErased) { - return Ok(()); + let start = if is_value_ns { "::<" } else { "<" }; + + let has_own_self = generics.has_self && generics.parent_count == 0; + let params = &generics.params[has_own_self as usize..]; + + // Don't print any regions if they're all erased. + let print_regions = params.iter().any(|param| { + match substs[param.index as usize].unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, } + }); + + // Don't print args that are the defaults of their respective parameters. + let num_supplied_defaults = if self.is_verbose { + 0 + } else { + params.iter().rev().take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default && substs[param.index as usize] == Kind::from( + self.tcx.type_of(param.def_id).subst(self.tcx, substs) + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) + } + }).count() + }; - for region in regions() { - let region: ty::Region<'_> = region; - start_or_continue(f, start, ", ")?; - if verbose { - write!(f, "{:?}", region)?; - } else { - let s = region.to_string(); - if s.is_empty() { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(f, "'_")?; + for param in ¶ms[..params.len() - num_supplied_defaults] { + match substs[param.index as usize].unpack() { + UnpackedKind::Lifetime(region) => { + if !print_regions { + continue; + } + start_or_continue(f, start, ", ")?; + if self.is_verbose { + write!(f, "{:?}", region)?; } else { - write!(f, "{}", s)?; + let s = region.to_string(); + if s.is_empty() { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + write!(f, "'_")?; + } else { + write!(f, "{}", s)?; + } } } + UnpackedKind::Type(ty) => { + start_or_continue(f, start, ", ")?; + ty.print_display(f, self)?; + } + UnpackedKind::Const(ct) => { + start_or_continue(f, start, ", ")?; + ct.print_display(f, self)?; + } } - - Ok(()) - }; - - print_regions(f, "<", 0, own_counts.lifetimes)?; - - let tps = substs.types() - .take(own_counts.types - num_supplied_defaults) - .skip(has_self as usize); - - for ty in tps { - start_or_continue(f, "<", ", ")?; - ty.print_display(f, self)?; } for projection in projections { - start_or_continue(f, "<", ", ")?; + start_or_continue(f, start, ", ")?; print!(f, self, write("{}=", self.tcx.associated_item(projection.item_def_id).ident), print_display(projection.ty))?; } - // FIXME(const_generics::defaults) - let consts = substs.consts(); - - for ct in consts { - start_or_continue(f, "<", ", ")?; - ct.print_display(f, self)?; - } - - start_or_continue(f, "", ">")?; - - // For values, also print their name and type parameters. - if is_value_path { - empty.set(true); - - if has_self { - write!(f, ">")?; - } - - if let Some(item_name) = item_name { - write!(f, "::{}", item_name)?; - } - - print_regions(f, "::<", own_counts.lifetimes, usize::MAX)?; - - // FIXME: consider being smart with defaults here too - for ty in substs.types().skip(own_counts.types) { - start_or_continue(f, "::<", ", ")?; - ty.print_display(f, self)?; - } - - start_or_continue(f, "", ">")?; - } - - Ok(()) + start_or_continue(f, "", ">") } fn in_binder(&mut self, f: &mut F, value: &ty::Binder) -> fmt::Result @@ -626,19 +531,34 @@ define_print! { ('tcx) &'tcx ty::List>, (self, f, cx) { display { // Generate the main trait ref, including associated types. - - // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let mut first = true; if let Some(principal) = self.principal() { - let principal = principal.with_self_ty(cx.tcx, dummy_self); - cx.parameterized( - f, - principal.def_id, - principal.substs, - self.projection_bounds(), - )?; + let mut resugared_principal = false; + + // Special-case `Fn(...) -> ...` and resugar it. + if !cx.is_verbose && cx.tcx.lang_items().fn_trait_kind(principal.def_id).is_some() { + if let Tuple(ref args) = principal.substs.type_at(0).sty { + let mut projections = self.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + print!(f, cx, write("{}", cx.tcx.item_path_str(principal.def_id)))?; + cx.fn_sig(f, args, false, proj.ty)?; + resugared_principal = true; + } + } + } + + if !resugared_principal { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(cx.tcx, dummy_self); + cx.parameterized( + f, + principal.def_id, + principal.substs, + self.projection_bounds(), + )?; + } first = false; } @@ -1468,12 +1388,7 @@ define_print! { define_print! { ('tcx) ty::ProjectionTy<'tcx>, (self, f, cx) { display { - // FIXME(tschottdorf): use something like - // parameterized(f, self.substs, self.item_def_id, &[]) - // (which currently ICEs). - let trait_ref = self.trait_ref(cx.tcx); - let item_name = cx.tcx.associated_item(self.item_def_id).ident; - print!(f, cx, print_debug(trait_ref), write("::{}", item_name)) + cx.parameterized(f, self.item_def_id, self.substs, iter::empty()) } } } @@ -1542,12 +1457,14 @@ define_print! { match self.unpack() { UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), UnpackedKind::Type(ty) => print!(f, cx, print(ty)), + UnpackedKind::Const(ct) => print!(f, cx, print(ct)), } } debug { match self.unpack() { UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), UnpackedKind::Type(ty) => print!(f, cx, print(ty)), + UnpackedKind::Const(ct) => print!(f, cx, print(ct)), } } } From 1c2a3c5d79b9c6ee2ab4257eda41f1a86b273ef5 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 9 Dec 2018 17:54:18 +0200 Subject: [PATCH 089/157] rustc: support impl's in PrintCx::parameterized. --- src/librustc/util/ppaux.rs | 16 ++++++++++++++++ src/test/ui/hygiene/impl_items.rs | 2 +- src/test/ui/hygiene/impl_items.stderr | 2 +- src/test/ui/issues/issue-22638.rs | 2 +- src/test/ui/issues/issue-22638.stderr | 2 +- src/test/ui/issues/issue-24322.stderr | 2 +- src/test/ui/issues/issue-29124.rs | 2 +- src/test/ui/issues/issue-29124.stderr | 2 +- src/test/ui/issues/issue-39559-2.stderr | 4 ++-- .../privacy/associated-item-privacy-inherent.rs | 6 +++--- .../associated-item-privacy-inherent.stderr | 6 +++--- .../ui/qualified/qualified-path-params.stderr | 2 +- 12 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 8dfa924c1dfc9..6667d37873310 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -352,6 +352,22 @@ impl PrintCx<'a, 'gcx, 'tcx> { write!(f, "::{}", key.disambiguated_data.data.as_interned_str())?; } else { + // Try to print `impl`s more like how you'd refer to their associated items. + if let DefPathData::Impl = key.disambiguated_data.data { + if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { + // HACK(eddyb) this is in lieu of more specific disambiguation. + print!(f, self, write("{}", self.tcx.item_path_str(def_id)))?; + + let trait_ref = trait_ref.subst(self.tcx, substs); + print!(f, self, print_debug(trait_ref))?; + } else { + let self_ty = self.tcx.type_of(def_id).subst(self.tcx, substs); + // FIXME(eddyb) omit the <> where possible. + print!(f, self, write("<"), print(self_ty), write(">"))?; + } + return Ok(()); + } + print!(f, self, write("{}", self.tcx.item_path_str(def_id)))?; } diff --git a/src/test/ui/hygiene/impl_items.rs b/src/test/ui/hygiene/impl_items.rs index 37794c6e0773c..d628573d51707 100644 --- a/src/test/ui/hygiene/impl_items.rs +++ b/src/test/ui/hygiene/impl_items.rs @@ -9,7 +9,7 @@ mod foo { } pub macro m() { - let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private + let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {::f}` is private } } diff --git a/src/test/ui/hygiene/impl_items.stderr b/src/test/ui/hygiene/impl_items.stderr index 418c2c73ba157..0a273bc98ff61 100644 --- a/src/test/ui/hygiene/impl_items.stderr +++ b/src/test/ui/hygiene/impl_items.stderr @@ -1,4 +1,4 @@ -error: type `for<'r> fn(&'r foo::S) {foo::S::f}` is private +error: type `for<'r> fn(&'r foo::S) {::f}` is private --> $DIR/impl_items.rs:12:23 | LL | let _: () = S.f(); diff --git a/src/test/ui/issues/issue-22638.rs b/src/test/ui/issues/issue-22638.rs index fab24404eba7d..ff58c7aaced03 100644 --- a/src/test/ui/issues/issue-22638.rs +++ b/src/test/ui/issues/issue-22638.rs @@ -50,7 +50,7 @@ struct D (Box
); impl D { pub fn matches(&self, f: &F) { - //~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure + //~^ ERROR reached the type-length limit while instantiating `::matches::<[closure let &D(ref a) = self; a.matches(f) } diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr index aff968f3618c1..65483abe5c7f9 100644 --- a/src/test/ui/issues/issue-22638.stderr +++ b/src/test/ui/issues/issue-22638.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `D::matches::$CLOSURE` +error: reached the type-length limit while instantiating `::matches::$CLOSURE` --> $DIR/issue-22638.rs:52:5 | LL | / pub fn matches(&self, f: &F) { diff --git a/src/test/ui/issues/issue-24322.stderr b/src/test/ui/issues/issue-24322.stderr index def373cf2c0a8..b284c8cf1172c 100644 --- a/src/test/ui/issues/issue-24322.stderr +++ b/src/test/ui/issues/issue-24322.stderr @@ -5,7 +5,7 @@ LL | let x: &fn(&B) -> u32 = &B::func; | ^^^^^^^^ expected fn pointer, found fn item | = note: expected type `&for<'r> fn(&'r B) -> u32` - found type `&for<'r> fn(&'r B) -> u32 {B::func}` + found type `&for<'r> fn(&'r B) -> u32 {::func}` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29124.rs b/src/test/ui/issues/issue-29124.rs index 1cd3f84f7a227..8062045a6c058 100644 --- a/src/test/ui/issues/issue-29124.rs +++ b/src/test/ui/issues/issue-29124.rs @@ -13,7 +13,7 @@ fn func() -> Ret { fn main() { Obj::func.x(); - //~^ ERROR no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope + //~^ ERROR no method named `x` found for type `fn() -> Ret {::func}` in the current scope func.x(); //~^ ERROR no method named `x` found for type `fn() -> Ret {func}` in the current scope } diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index 3beb728978884..67f188e0588e2 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope +error[E0599]: no method named `x` found for type `fn() -> Ret {::func}` in the current scope --> $DIR/issue-29124.rs:15:15 | LL | Obj::func.x(); diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/issues/issue-39559-2.stderr index 700dbe3647497..ca2f2a5ba2845 100644 --- a/src/test/ui/issues/issue-39559-2.stderr +++ b/src/test/ui/issues/issue-39559-2.stderr @@ -8,7 +8,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-39559-2.rs:14:24 | LL | let array: [usize; Dim3::dim()] - | ^^^^^^^^^^^ calling non-const function `::dim` + | ^^^^^^^^^^^ calling non-const function `::dim` error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants --> $DIR/issue-39559-2.rs:17:15 @@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-39559-2.rs:17:15 | LL | = [0; Dim3::dim()]; - | ^^^^^^^^^^^ calling non-const function `::dim` + | ^^^^^^^^^^^ calling non-const function `::dim` error: aborting due to 4 previous errors diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.rs b/src/test/ui/privacy/associated-item-privacy-inherent.rs index c3ae920238f18..b6fd22fa669e0 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.rs +++ b/src/test/ui/privacy/associated-item-privacy-inherent.rs @@ -11,11 +11,11 @@ mod priv_nominal { pub macro mac() { let value = Pub::method; - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private value; - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private Pub.method(); - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private Pub::CONST; //~^ ERROR associated constant `CONST` is private // let _: Pub::AssocTy; diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.stderr b/src/test/ui/privacy/associated-item-privacy-inherent.stderr index 6471a7914e103..69be9d2cea6df 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.stderr +++ b/src/test/ui/privacy/associated-item-privacy-inherent.stderr @@ -1,4 +1,4 @@ -error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private --> $DIR/associated-item-privacy-inherent.rs:13:21 | LL | let value = Pub::method; @@ -7,7 +7,7 @@ LL | let value = Pub::method; LL | priv_nominal::mac!(); | --------------------- in this macro invocation -error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private --> $DIR/associated-item-privacy-inherent.rs:15:9 | LL | value; @@ -16,7 +16,7 @@ LL | value; LL | priv_nominal::mac!(); | --------------------- in this macro invocation -error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private --> $DIR/associated-item-privacy-inherent.rs:17:13 | LL | Pub.method(); diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index 926b098040f14..6315ec2e5126b 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -11,7 +11,7 @@ LL | 0 ..= ::A::f:: => {} | ^^^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types | = note: start type: {integer} - = note: end type: fn() {S::f::} + = note: end type: fn() {::f::} error: aborting due to 2 previous errors From 7505bb6bbb7d66f445d7df7afc7c397dadea26f8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 3 Feb 2019 12:24:29 +0200 Subject: [PATCH 090/157] rustc_codegen_utils: revert some symbol_names refactors (while keeping the functional changes). --- src/librustc_codegen_utils/symbol_names.rs | 123 +++++++++------------ 1 file changed, 55 insertions(+), 68 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 91301158abdb0..70ab185660c4c 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -380,88 +380,75 @@ impl SymbolPathBuffer { let _ = write!(self.result, "17h{:016x}E", hash); self.result } +} - // Name sanitation. LLVM will happily accept identifiers with weird names, but - // gas doesn't! - // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ - // NVPTX assembly has more strict naming rules than gas, so additionally, dots - // are replaced with '$' there. - fn sanitize_and_append(&mut self, s: &str) { - self.temp_buf.clear(); - - for c in s.chars() { - match c { - // Escape these with $ sequences - '@' => self.temp_buf.push_str("$SP$"), - '*' => self.temp_buf.push_str("$BP$"), - '&' => self.temp_buf.push_str("$RF$"), - '<' => self.temp_buf.push_str("$LT$"), - '>' => self.temp_buf.push_str("$GT$"), - '(' => self.temp_buf.push_str("$LP$"), - ')' => self.temp_buf.push_str("$RP$"), - ',' => self.temp_buf.push_str("$C$"), - - '-' | ':' => if self.strict_naming { - // NVPTX doesn't support these characters in symbol names. - self.temp_buf.push('$') - } - else { - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - self.temp_buf.push('.') - }, - - '.' => if self.strict_naming { - self.temp_buf.push('$') - } - else { - self.temp_buf.push('.') - }, - - // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c), - - _ => { - self.temp_buf.push('$'); - for c in c.escape_unicode().skip(1) { - match c { - '{' => {} - '}' => self.temp_buf.push('$'), - c => self.temp_buf.push(c), - } - } - } - } - } - - let need_underscore = { - // Underscore-qualify anything that didn't start as an ident. - !self.temp_buf.is_empty() - && self.temp_buf.as_bytes()[0] != '_' as u8 - && !(self.temp_buf.as_bytes()[0] as char).is_xid_start() - }; +impl ItemPathBuffer for SymbolPathBuffer { + fn root_mode(&self) -> &RootMode { + const ABSOLUTE: &RootMode = &RootMode::Absolute; + ABSOLUTE + } + fn push(&mut self, text: &str) { + self.temp_buf.clear(); + let need_underscore = sanitize(&mut self.temp_buf, text, self.strict_naming); let _ = write!( self.result, "{}", self.temp_buf.len() + (need_underscore as usize) ); - if need_underscore { self.result.push('_'); } - self.result.push_str(&self.temp_buf); } } -impl ItemPathBuffer for SymbolPathBuffer { - fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &RootMode = &RootMode::Absolute; - ABSOLUTE - } +// Name sanitation. LLVM will happily accept identifiers with weird names, but +// gas doesn't! +// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ +// NVPTX assembly has more strict naming rules than gas, so additionally, dots +// are replaced with '$' there. +// +// returns true if an underscore must be added at the start +fn sanitize(result: &mut String, s: &str, strict_naming: bool) -> bool { + for c in s.chars() { + match c { + // Escape these with $ sequences + '@' => result.push_str("$SP$"), + '*' => result.push_str("$BP$"), + '&' => result.push_str("$RF$"), + '<' => result.push_str("$LT$"), + '>' => result.push_str("$GT$"), + '(' => result.push_str("$LP$"), + ')' => result.push_str("$RP$"), + ',' => result.push_str("$C$"), + + '-' | ':' | '.' if strict_naming => { + // NVPTX doesn't support these characters in symbol names. + result.push('$') + } - fn push(&mut self, text: &str) { - self.sanitize_and_append(text); + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + '-' | ':' => result.push('.'), + + // These are legal symbols + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c), + + _ => { + result.push('$'); + for c in c.escape_unicode().skip(1) { + match c { + '{' => {} + '}' => result.push('$'), + c => result.push(c), + } + } + } + } } + + // Underscore-qualify anything that didn't start as an ident. + !result.is_empty() && result.as_bytes()[0] != '_' as u8 + && !(result.as_bytes()[0] as char).is_xid_start() } From 7d211e5b1287f9140418c4e46461c451d1da42e1 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 9 Dec 2018 21:05:22 +0200 Subject: [PATCH 091/157] rustc: rewrite ty::item_path to be more functional than mutation-oriented. --- src/librustc/ty/item_path.rs | 236 ++++++++++++--------- src/librustc_codegen_utils/symbol_names.rs | 65 ++++-- 2 files changed, 172 insertions(+), 129 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 6734e264305a7..1eb3952032a6d 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -65,10 +65,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { RootMode::Local } }); - let mut buffer = LocalPathBuffer::new(mode); - debug!("item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id); - buffer.into_string() + let mut printer = LocalPathPrinter::new(mode); + debug!("item_path_str: printer={:?} def_id={:?}", printer, def_id); + self.print_item_path(&mut printer, def_id) } /// Returns a string identifying this local node-id. @@ -79,23 +78,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { - let mut buffer = LocalPathBuffer::new(RootMode::Absolute); - debug!("absolute_item_path_str: buffer={:?} def_id={:?}", buffer, def_id); - self.push_item_path(&mut buffer, def_id); - buffer.into_string() + let mut printer = LocalPathPrinter::new(RootMode::Absolute); + debug!("absolute_item_path_str: printer={:?} def_id={:?}", printer, def_id); + self.print_item_path(&mut printer, def_id) } /// Returns the "path" to a particular crate. This can proceed in - /// various ways, depending on the `root_mode` of the `buffer`. + /// various ways, depending on the `root_mode` of the `printer`. /// (See `RootMode` enum for more details.) - pub fn push_krate_path(self, buffer: &mut T, cnum: CrateNum) - where T: ItemPathBuffer + Debug + fn print_krate_path

( + self, + printer: &mut P, + cnum: CrateNum, + ) -> P::Path + where P: ItemPathPrinter + Debug { debug!( - "push_krate_path: buffer={:?} cnum={:?} LOCAL_CRATE={:?}", - buffer, cnum, LOCAL_CRATE + "print_krate_path: printer={:?} cnum={:?} LOCAL_CRATE={:?}", + printer, cnum, LOCAL_CRATE ); - match *buffer.root_mode() { + match printer.root_mode() { RootMode::Local => { // In local mode, when we encounter a crate other than // LOCAL_CRATE, execution proceeds in one of two ways: @@ -117,56 +119,60 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { span, .. }) if !span.is_dummy() => { - debug!("push_krate_path: def_id={:?}", def_id); - self.push_item_path(buffer, def_id); + debug!("print_krate_path: def_id={:?}", def_id); + self.print_item_path(printer, def_id) } _ => { let name = self.crate_name(cnum).as_str(); - debug!("push_krate_path: name={:?}", name); - buffer.push(&name); + debug!("print_krate_path: name={:?}", name); + printer.path_crate(Some(&name)) } } } else if self.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - buffer.push(&keywords::Crate.name().as_str()) + printer.path_crate(Some(&keywords::Crate.name().as_str())) + } else { + printer.path_crate(None) } + } else { + printer.path_crate(None) } } RootMode::Absolute => { // In absolute mode, just write the crate name // unconditionally. let name = self.original_crate_name(cnum).as_str(); - debug!("push_krate_path: original_name={:?}", name); - buffer.push(&name); + debug!("print_krate_path: original_name={:?}", name); + printer.path_crate(Some(&name)) } } } - /// If possible, this pushes a global path resolving to `external_def_id` that is visible + /// If possible, this returns a global path resolving to `external_def_id` that is visible /// from at least one local module and returns true. If the crate defining `external_def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - pub fn try_push_visible_item_path( + fn try_print_visible_item_path

( self, - buffer: &mut T, + printer: &mut P, external_def_id: DefId, - ) -> bool - where T: ItemPathBuffer + Debug + ) -> Option + where P: ItemPathPrinter + Debug { debug!( - "try_push_visible_item_path: buffer={:?} external_def_id={:?}", - buffer, external_def_id + "try_print_visible_item_path: printer={:?} external_def_id={:?}", + printer, external_def_id ); let visible_parent_map = self.visible_parent_map(LOCAL_CRATE); let (mut cur_def, mut cur_path) = (external_def_id, Vec::::new()); loop { debug!( - "try_push_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}", + "try_print_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}", cur_def, cur_path, CRATE_DEF_INDEX, ); - // If `cur_def` is a direct or injected extern crate, push the path to the crate - // followed by the path to the item within the crate and return. + // If `cur_def` is a direct or injected extern crate, return the path to the crate + // followed by the path to the item within the crate. if cur_def.index == CRATE_DEF_INDEX { match *self.extern_crate(cur_def) { Some(ExternCrate { @@ -175,26 +181,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { span, .. }) => { - debug!("try_push_visible_item_path: def_id={:?}", def_id); - if !span.is_dummy() { - self.push_item_path(buffer, def_id); + debug!("try_print_visible_item_path: def_id={:?}", def_id); + let path = if !span.is_dummy() { + self.print_item_path(printer, def_id) } else { - buffer.push(&self.crate_name(cur_def.krate).as_str()); - } - cur_path.iter().rev().for_each(|segment| buffer.push(&segment)); - return true; + printer.path_crate(Some( + &self.crate_name(cur_def.krate).as_str(), + )) + }; + return Some(cur_path.iter().rev().fold(path, |path, segment| { + printer.path_append(path, &segment) + })); } None => { - buffer.push(&self.crate_name(cur_def.krate).as_str()); - cur_path.iter().rev().for_each(|segment| buffer.push(&segment)); - return true; + let path = printer.path_crate(Some( + &self.crate_name(cur_def.krate).as_str(), + )); + return Some(cur_path.iter().rev().fold(path, |path, segment| { + printer.path_append(path, &segment) + })); } _ => {}, } } let mut cur_def_key = self.def_key(cur_def); - debug!("try_push_visible_item_path: cur_def_key={:?}", cur_def_key); + debug!("try_print_visible_item_path: cur_def_key={:?}", cur_def_key); // For a UnitStruct or TupleStruct we want the name of its parent rather than . if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { @@ -211,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let data = cur_def_key.disambiguated_data.data; debug!( - "try_push_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", + "try_print_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", data, visible_parent, actual_parent, ); let symbol = match data { @@ -268,39 +280,44 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }) }, }; - debug!("try_push_visible_item_path: symbol={:?}", symbol); + debug!("try_print_visible_item_path: symbol={:?}", symbol); cur_path.push(symbol); - match visible_parent { - Some(def) => cur_def = def, - None => return false, - }; + cur_def = visible_parent?; } } - pub fn push_item_path(self, buffer: &mut T, def_id: DefId) - where T: ItemPathBuffer + Debug + pub fn print_item_path

( + self, + printer: &mut P, + def_id: DefId, + ) -> P::Path + where P: ItemPathPrinter + Debug { debug!( - "push_item_path: buffer={:?} def_id={:?}", - buffer, def_id + "print_item_path: printer={:?} def_id={:?}", + printer, def_id ); - match *buffer.root_mode() { - RootMode::Local if !def_id.is_local() => - if self.try_push_visible_item_path(buffer, def_id) { return }, + match printer.root_mode() { + RootMode::Local if !def_id.is_local() => { + match self.try_print_visible_item_path(printer, def_id) { + Some(path) => return path, + None => {} + } + } _ => {} } let key = self.def_key(def_id); - debug!("push_item_path: key={:?}", key); + debug!("print_item_path: key={:?}", key); match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); - self.push_krate_path(buffer, def_id.krate); + self.print_krate_path(printer, def_id.krate) } DefPathData::Impl => { - self.push_impl_path(buffer, def_id); + self.print_impl_path(printer, def_id) } // Unclear if there is any value in distinguishing these. @@ -325,26 +342,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::ClosureExpr | data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { - let parent_def_id = self.parent_def_id(def_id).unwrap(); - self.push_item_path(buffer, parent_def_id); - buffer.push(&data.as_interned_str().as_symbol().as_str()); + let parent_did = self.parent_def_id(def_id).unwrap(); + let path = self.print_item_path(printer, parent_did); + printer.path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.parent_def_id(def_id).unwrap(); - self.push_item_path(buffer, parent_def_id); + self.print_item_path(printer, parent_def_id) } } } - fn push_impl_path( + fn print_impl_path

( self, - buffer: &mut T, + printer: &mut P, impl_def_id: DefId, - ) - where T: ItemPathBuffer + Debug + ) -> P::Path + where P: ItemPathPrinter + Debug { - debug!("push_impl_path: buffer={:?} impl_def_id={:?}", buffer, impl_def_id); + debug!("print_impl_path: printer={:?} impl_def_id={:?}", printer, impl_def_id); let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); // Always use types for non-local impls, where types are always @@ -356,7 +373,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; if !use_types { - return self.push_impl_path_fallback(buffer, impl_def_id); + return self.print_impl_path_fallback(printer, impl_def_id); } // Decide whether to print the parent path for the impl. @@ -380,13 +397,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - self.push_item_path(buffer, parent_def_id); + let path = self.print_item_path(printer, parent_def_id); if let Some(trait_ref) = impl_trait_ref { - buffer.push(&format!("", trait_ref, self_ty)); + return printer.path_append(path, &format!("", trait_ref, self_ty)); } else { - buffer.push(&format!("", self_ty)); + return printer.path_append(path, &format!("", self_ty)); } - return; } // Otherwise, try to give a good form that would be valid language @@ -394,8 +410,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(trait_ref) = impl_trait_ref { // Trait impls. - buffer.push(&format!("<{} as {}>", self_ty, trait_ref)); - return; + return printer.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); } // Inherent impls. Try to print `Foo::bar` for an inherent @@ -403,14 +418,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // anything other than a simple path. match self_ty.sty { ty::Adt(adt_def, substs) => { + // FIXME(eddyb) always print without <> here. if substs.types().next().is_none() { // ignore regions - self.push_item_path(buffer, adt_def.did); + self.print_item_path(printer, adt_def.did) } else { - buffer.push(&format!("<{}>", self_ty)); + printer.path_impl(&format!("<{}>", self_ty)) } } - ty::Foreign(did) => self.push_item_path(buffer, did), + ty::Foreign(did) => self.print_item_path(printer, did), ty::Bool | ty::Char | @@ -418,31 +434,31 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::Uint(_) | ty::Float(_) | ty::Str => { - buffer.push(&self_ty.to_string()); + printer.path_impl(&self_ty.to_string()) } _ => { - buffer.push(&format!("<{}>", self_ty)); + printer.path_impl(&format!("<{}>", self_ty)) } } } - fn push_impl_path_fallback( + fn print_impl_path_fallback

( self, - buffer: &mut T, + printer: &mut P, impl_def_id: DefId, - ) - where T: ItemPathBuffer + Debug + ) -> P::Path + where P: ItemPathPrinter + Debug { // If no type info is available, fall back to // pretty printing some span information. This should // only occur very early in the compiler pipeline. let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); - self.push_item_path(buffer, parent_def_id); + let path = self.print_item_path(printer, parent_def_id); let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap(); let item = self.hir().expect_item_by_hir_id(hir_id); let span_str = self.sess.source_map().span_to_string(item.span); - buffer.push(&format!("", span_str)); + printer.path_append(path, &format!("", span_str)) } /// Returns the `DefId` of `def_id`'s parent in the def tree. If @@ -505,12 +521,17 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { /// Unifying Trait for different kinds of item paths we might /// construct. The basic interface is that components get pushed: the /// instance can also customize how we handle the root of a crate. -pub trait ItemPathBuffer { - fn root_mode(&self) -> &RootMode; - fn push(&mut self, text: &str); +pub trait ItemPathPrinter { + type Path; + + fn root_mode(&self) -> RootMode; + + fn path_crate(&self, name: Option<&str>) -> Self::Path; + fn path_impl(&self, text: &str) -> Self::Path; + fn path_append(&self, path: Self::Path, text: &str) -> Self::Path; } -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub enum RootMode { /// Try to make a path relative to the local crate. In /// particular, local paths have no prefix, and if the path comes @@ -524,33 +545,36 @@ pub enum RootMode { } #[derive(Debug)] -struct LocalPathBuffer { +struct LocalPathPrinter { root_mode: RootMode, - str: String, } -impl LocalPathBuffer { - fn new(root_mode: RootMode) -> LocalPathBuffer { - LocalPathBuffer { +impl LocalPathPrinter { + fn new(root_mode: RootMode) -> LocalPathPrinter { + LocalPathPrinter { root_mode, - str: String::new(), } } - - fn into_string(self) -> String { - self.str - } } -impl ItemPathBuffer for LocalPathBuffer { - fn root_mode(&self) -> &RootMode { - &self.root_mode +impl ItemPathPrinter for LocalPathPrinter { + type Path = String; + + fn root_mode(&self) -> RootMode { + self.root_mode } - fn push(&mut self, text: &str) { - if !self.str.is_empty() { - self.str.push_str("::"); + fn path_crate(&self, name: Option<&str>) -> Self::Path { + name.unwrap_or("").to_string() + } + fn path_impl(&self, text: &str) -> Self::Path { + text.to_string() + } + fn path_append(&self, mut path: Self::Path, text: &str) -> Self::Path { + if !path.is_empty() { + path.push_str("::"); } - self.str.push_str(text); + path.push_str(text); + path } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 70ab185660c4c..13f8e13c3288d 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -92,7 +92,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; +use rustc::ty::item_path::{self, ItemPathPrinter, RootMode}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -223,11 +223,9 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - let mut buffer = SymbolPathBuffer::new(tcx); item_path::with_forced_absolute_paths(|| { - tcx.push_item_path(&mut buffer, def_id); - }); - buffer.into_interned() + tcx.push_item_path(&mut SymbolPath::new(tcx), def_id).into_interned() + }) } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -319,7 +317,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx); + let mut buf = SymbolPath::from_interned(tcx.def_symbol_name(def_id), tcx); if instance.is_vtable_shim() { buf.push("{{vtable-shim}}"); @@ -342,15 +340,15 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. #[derive(Debug)] -struct SymbolPathBuffer { +struct SymbolPath { result: String, temp_buf: String, strict_naming: bool, } -impl SymbolPathBuffer { +impl SymbolPath { fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { - let mut result = SymbolPathBuffer { + let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), strict_naming: tcx.has_strict_asm_symbol_naming(), @@ -360,7 +358,7 @@ impl SymbolPathBuffer { } fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { - let mut result = SymbolPathBuffer { + let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), strict_naming: tcx.has_strict_asm_symbol_naming(), @@ -375,19 +373,6 @@ impl SymbolPathBuffer { } } - fn finish(mut self, hash: u64) -> String { - // E = end name-sequence - let _ = write!(self.result, "17h{:016x}E", hash); - self.result - } -} - -impl ItemPathBuffer for SymbolPathBuffer { - fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &RootMode = &RootMode::Absolute; - ABSOLUTE - } - fn push(&mut self, text: &str) { self.temp_buf.clear(); let need_underscore = sanitize(&mut self.temp_buf, text, self.strict_naming); @@ -401,6 +386,40 @@ impl ItemPathBuffer for SymbolPathBuffer { } self.result.push_str(&self.temp_buf); } + + fn finish(mut self, hash: u64) -> String { + // E = end name-sequence + let _ = write!(self.result, "17h{:016x}E", hash); + self.result + } +} + +#[derive(Debug)] +struct SymbolPathPrinter; + +impl ItemPathPrinter for SymbolPathPrinter { + type Path = SymbolPath; + + fn root_mode(&self) ->RootMode { + RootMode::Absolute + } + + fn path_crate(&self, name: Option<&str>) -> Self::Path { + let mut path = SymbolPath::new(); + if let Some(name) = name { + path.push(name); + } + path + } + fn path_impl(&self, text: &str) -> Self::Path { + let mut path = SymbolPath::new(); + path.push(text); + path + } + fn path_append(&self, mut path: Self::Path, text: &str) -> Self::Path { + path.push(text); + path + } } // Name sanitation. LLVM will happily accept identifiers with weird names, but From 387cacf76bdee1af073f53948af382ca78d046e6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 10 Dec 2018 12:59:08 +0200 Subject: [PATCH 092/157] rustc: remove ty::item_path::RootMode by moving local logic into the printer. --- src/librustc/ty/item_path.rs | 543 +++++++++------------ src/librustc/ty/print.rs | 26 +- src/librustc_codegen_utils/symbol_names.rs | 27 +- src/librustdoc/clean/mod.rs | 33 +- 4 files changed, 273 insertions(+), 356 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 1eb3952032a6d..6f8d0d19103ea 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -2,11 +2,11 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; +use ty::print::PrintCx; use syntax::ast; -use syntax::symbol::{keywords, LocalInternedString, Symbol}; +use syntax::symbol::{keywords, Symbol}; use std::cell::Cell; -use std::fmt::Debug; thread_local! { static FORCE_ABSOLUTE: Cell = Cell::new(false); @@ -58,16 +58,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// suitable for user output. It is relative to the current crate /// root, unless with_forced_absolute_paths was used. pub fn item_path_str(self, def_id: DefId) -> String { - let mode = FORCE_ABSOLUTE.with(|force| { - if force.get() { - RootMode::Absolute - } else { - RootMode::Local - } - }); - let mut printer = LocalPathPrinter::new(mode); - debug!("item_path_str: printer={:?} def_id={:?}", printer, def_id); - self.print_item_path(&mut printer, def_id) + debug!("item_path_str: def_id={:?}", def_id); + let mut cx = PrintCx::new(self); + if FORCE_ABSOLUTE.with(|force| force.get()) { + AbsolutePathPrinter::print_item_path(&mut cx, def_id) + } else { + LocalPathPrinter::print_item_path(&mut cx, def_id) + } } /// Returns a string identifying this local node-id. @@ -78,246 +75,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { - let mut printer = LocalPathPrinter::new(RootMode::Absolute); - debug!("absolute_item_path_str: printer={:?} def_id={:?}", printer, def_id); - self.print_item_path(&mut printer, def_id) - } - - /// Returns the "path" to a particular crate. This can proceed in - /// various ways, depending on the `root_mode` of the `printer`. - /// (See `RootMode` enum for more details.) - fn print_krate_path

( - self, - printer: &mut P, - cnum: CrateNum, - ) -> P::Path - where P: ItemPathPrinter + Debug - { - debug!( - "print_krate_path: printer={:?} cnum={:?} LOCAL_CRATE={:?}", - printer, cnum, LOCAL_CRATE - ); - match printer.root_mode() { - RootMode::Local => { - // In local mode, when we encounter a crate other than - // LOCAL_CRATE, execution proceeds in one of two ways: - // - // 1. for a direct dependency, where user added an - // `extern crate` manually, we put the `extern - // crate` as the parent. So you wind up with - // something relative to the current crate. - // 2. for an extern inferred from a path or an indirect crate, - // where there is no explicit `extern crate`, we just prepend - // the crate name. - // - // Returns `None` for the local crate. - if cnum != LOCAL_CRATE { - match *self.extern_crate(cnum.as_def_id()) { - Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - span, - .. - }) if !span.is_dummy() => { - debug!("print_krate_path: def_id={:?}", def_id); - self.print_item_path(printer, def_id) - } - _ => { - let name = self.crate_name(cnum).as_str(); - debug!("print_krate_path: name={:?}", name); - printer.path_crate(Some(&name)) - } - } - } else if self.sess.rust_2018() { - // We add the `crate::` keyword on Rust 2018, only when desired. - if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - printer.path_crate(Some(&keywords::Crate.name().as_str())) - } else { - printer.path_crate(None) - } - } else { - printer.path_crate(None) - } - } - RootMode::Absolute => { - // In absolute mode, just write the crate name - // unconditionally. - let name = self.original_crate_name(cnum).as_str(); - debug!("print_krate_path: original_name={:?}", name); - printer.path_crate(Some(&name)) - } - } - } - - /// If possible, this returns a global path resolving to `external_def_id` that is visible - /// from at least one local module and returns true. If the crate defining `external_def_id` is - /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_item_path

( - self, - printer: &mut P, - external_def_id: DefId, - ) -> Option - where P: ItemPathPrinter + Debug - { - debug!( - "try_print_visible_item_path: printer={:?} external_def_id={:?}", - printer, external_def_id - ); - let visible_parent_map = self.visible_parent_map(LOCAL_CRATE); - - let (mut cur_def, mut cur_path) = (external_def_id, Vec::::new()); - loop { - debug!( - "try_print_visible_item_path: cur_def={:?} cur_path={:?} CRATE_DEF_INDEX={:?}", - cur_def, cur_path, CRATE_DEF_INDEX, - ); - // If `cur_def` is a direct or injected extern crate, return the path to the crate - // followed by the path to the item within the crate. - if cur_def.index == CRATE_DEF_INDEX { - match *self.extern_crate(cur_def) { - Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - span, - .. - }) => { - debug!("try_print_visible_item_path: def_id={:?}", def_id); - let path = if !span.is_dummy() { - self.print_item_path(printer, def_id) - } else { - printer.path_crate(Some( - &self.crate_name(cur_def.krate).as_str(), - )) - }; - return Some(cur_path.iter().rev().fold(path, |path, segment| { - printer.path_append(path, &segment) - })); - } - None => { - let path = printer.path_crate(Some( - &self.crate_name(cur_def.krate).as_str(), - )); - return Some(cur_path.iter().rev().fold(path, |path, segment| { - printer.path_append(path, &segment) - })); - } - _ => {}, - } - } - - let mut cur_def_key = self.def_key(cur_def); - debug!("try_print_visible_item_path: cur_def_key={:?}", cur_def_key); - - // For a UnitStruct or TupleStruct we want the name of its parent rather than . - if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { - let parent = DefId { - krate: cur_def.krate, - index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), - }; - - cur_def_key = self.def_key(parent); - } - - let visible_parent = visible_parent_map.get(&cur_def).cloned(); - let actual_parent = self.parent(cur_def); - - let data = cur_def_key.disambiguated_data.data; - debug!( - "try_print_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", - data, visible_parent, actual_parent, - ); - let symbol = match data { - // In order to output a path that could actually be imported (valid and visible), - // we need to handle re-exports correctly. - // - // For example, take `std::os::unix::process::CommandExt`, this trait is actually - // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). - // - // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is - // private so the "true" path to `CommandExt` isn't accessible. - // - // In this case, the `visible_parent_map` will look something like this: - // - // (child) -> (parent) - // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` - // `std::sys::unix::ext::process` -> `std::sys::unix::ext` - // `std::sys::unix::ext` -> `std::os` - // - // This is correct, as the visible parent of `std::sys::unix::ext` is in fact - // `std::os`. - // - // When printing the path to `CommandExt` and looking at the `cur_def_key` that - // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go - // to the parent - resulting in a mangled path like - // `std::os::ext::process::CommandExt`. - // - // Instead, we must detect that there was a re-export and instead print `unix` - // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To - // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with - // the visible parent (`std::os`). If these do not match, then we iterate over - // the children of the visible parent (as was done when computing - // `visible_parent_map`), looking for the specific child we currently have and then - // have access to the re-exported name. - DefPathData::Module(actual_name) | - DefPathData::TypeNs(actual_name) if visible_parent != actual_parent => { - visible_parent - .and_then(|parent| { - self.item_children(parent) - .iter() - .find(|child| child.def.def_id() == cur_def) - .map(|child| child.ident.as_str()) - }) - .unwrap_or_else(|| actual_name.as_str()) - }, - _ => { - data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { - // Re-exported `extern crate` (#43189). - if let DefPathData::CrateRoot = data { - self.original_crate_name(cur_def.krate).as_str() - } else { - Symbol::intern("").as_str() - } - }) - }, - }; - debug!("try_print_visible_item_path: symbol={:?}", symbol); - cur_path.push(symbol); - - cur_def = visible_parent?; - } + debug!("absolute_item_path_str: def_id={:?}", def_id); + let mut cx = PrintCx::new(self); + AbsolutePathPrinter::print_item_path(&mut cx, def_id) } +} - pub fn print_item_path

( - self, - printer: &mut P, - def_id: DefId, - ) -> P::Path - where P: ItemPathPrinter + Debug +impl PrintCx<'a, 'gcx, 'tcx> { + pub fn default_print_item_path

(&mut self, def_id: DefId) -> P::Path + where P: ItemPathPrinter { - debug!( - "print_item_path: printer={:?} def_id={:?}", - printer, def_id - ); - match printer.root_mode() { - RootMode::Local if !def_id.is_local() => { - match self.try_print_visible_item_path(printer, def_id) { - Some(path) => return path, - None => {} - } - } - _ => {} - } - - let key = self.def_key(def_id); - debug!("print_item_path: key={:?}", key); + debug!("default_print_item_path: def_id={:?}", def_id); + let key = self.tcx.def_key(def_id); + debug!("default_print_item_path: key={:?}", key); match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); - self.print_krate_path(printer, def_id.krate) + P::path_crate(self, def_id.krate) } DefPathData::Impl => { - self.print_impl_path(printer, def_id) + self.default_print_impl_path::

(def_id) } // Unclear if there is any value in distinguishing these. @@ -342,27 +120,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::ClosureExpr | data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.parent_def_id(def_id).unwrap(); - let path = self.print_item_path(printer, parent_did); - printer.path_append(path, &data.as_interned_str().as_symbol().as_str()) + let parent_did = self.tcx.parent_def_id(def_id).unwrap(); + let path = P::print_item_path(self, parent_did); + P::path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` - let parent_def_id = self.parent_def_id(def_id).unwrap(); - self.print_item_path(printer, parent_def_id) + let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); + P::print_item_path(self, parent_def_id) } } } - fn print_impl_path

( - self, - printer: &mut P, - impl_def_id: DefId, - ) -> P::Path - where P: ItemPathPrinter + Debug + fn default_print_impl_path

(&mut self, impl_def_id: DefId) -> P::Path + where P: ItemPathPrinter { - debug!("print_impl_path: printer={:?} impl_def_id={:?}", printer, impl_def_id); - let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); + debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); + let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); // Always use types for non-local impls, where types are always // available, and filename/line-number is mostly uninteresting. @@ -373,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; if !use_types { - return self.print_impl_path_fallback(printer, impl_def_id); + return self.default_print_impl_path_fallback::

(impl_def_id); } // Decide whether to print the parent path for the impl. @@ -381,27 +155,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let self_ty = self.type_of(impl_def_id); + let self_ty = self.tcx.type_of(impl_def_id); let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, - Some(ty_def_id) => self.parent_def_id(ty_def_id) == Some(parent_def_id), + Some(ty_def_id) => self.tcx.parent_def_id(ty_def_id) == Some(parent_def_id), }; - let impl_trait_ref = self.impl_trait_ref(impl_def_id); + let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); let in_trait_mod = match impl_trait_ref { None => false, - Some(trait_ref) => self.parent_def_id(trait_ref.def_id) == Some(parent_def_id), + Some(trait_ref) => self.tcx.parent_def_id(trait_ref.def_id) == Some(parent_def_id), }; if !in_self_mod && !in_trait_mod { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = self.print_item_path(printer, parent_def_id); + let path = P::print_item_path(self, parent_def_id); if let Some(trait_ref) = impl_trait_ref { - return printer.path_append(path, &format!("", trait_ref, self_ty)); + return P::path_append(path, &format!("", trait_ref, self_ty)); } else { - return printer.path_append(path, &format!("", self_ty)); + return P::path_append(path, &format!("", self_ty)); } } @@ -410,7 +184,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(trait_ref) = impl_trait_ref { // Trait impls. - return printer.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); + return P::path_impl(self, &format!("<{} as {}>", self_ty, trait_ref)); } // Inherent impls. Try to print `Foo::bar` for an inherent @@ -420,13 +194,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::Adt(adt_def, substs) => { // FIXME(eddyb) always print without <> here. if substs.types().next().is_none() { // ignore regions - self.print_item_path(printer, adt_def.did) + P::print_item_path(self, adt_def.did) } else { - printer.path_impl(&format!("<{}>", self_ty)) + P::path_impl(self, &format!("<{}>", self_ty)) } } - ty::Foreign(did) => self.print_item_path(printer, did), + ty::Foreign(did) => P::print_item_path(self, did), ty::Bool | ty::Char | @@ -434,33 +208,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::Uint(_) | ty::Float(_) | ty::Str => { - printer.path_impl(&self_ty.to_string()) + P::path_impl(self, &self_ty.to_string()) } _ => { - printer.path_impl(&format!("<{}>", self_ty)) + P::path_impl(self, &format!("<{}>", self_ty)) } } } - fn print_impl_path_fallback

( - self, - printer: &mut P, - impl_def_id: DefId, - ) -> P::Path - where P: ItemPathPrinter + Debug + fn default_print_impl_path_fallback

(&mut self, impl_def_id: DefId) -> P::Path + where P: ItemPathPrinter { // If no type info is available, fall back to // pretty printing some span information. This should // only occur very early in the compiler pipeline. - let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); - let path = self.print_item_path(printer, parent_def_id); - let hir_id = self.hir().as_local_hir_id(impl_def_id).unwrap(); - let item = self.hir().expect_item_by_hir_id(hir_id); - let span_str = self.sess.source_map().span_to_string(item.span); - printer.path_append(path, &format!("", span_str)) + // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` + let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); + let path = P::print_item_path(self, parent_def_id); + let hir_id = self.tcx.hir().as_local_hir_id(impl_def_id).unwrap(); + let item = self.tcx.hir().expect_item_by_hir_id(hir_id); + let span_str = self.tcx.sess.source_map().span_to_string(item.span); + P::path_append(path, &format!("", span_str)) } +} +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns the `DefId` of `def_id`'s parent in the def tree. If /// this returns `None`, then `def_id` represents a crate root or /// inlined root. @@ -519,58 +292,202 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { } /// Unifying Trait for different kinds of item paths we might -/// construct. The basic interface is that components get pushed: the -/// instance can also customize how we handle the root of a crate. -pub trait ItemPathPrinter { +/// construct. The basic interface is that components get appended. +pub trait ItemPathPrinter: Sized { type Path; - fn root_mode(&self) -> RootMode; + fn print_item_path(cx: &mut PrintCx<'_, '_, '_>, def_id: DefId) -> Self::Path { + cx.default_print_item_path::(def_id) + } - fn path_crate(&self, name: Option<&str>) -> Self::Path; - fn path_impl(&self, text: &str) -> Self::Path; - fn path_append(&self, path: Self::Path, text: &str) -> Self::Path; + fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path; + fn path_impl(cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path; + fn path_append(path: Self::Path, text: &str) -> Self::Path; } -#[derive(Copy, Clone, Debug)] -pub enum RootMode { - /// Try to make a path relative to the local crate. In - /// particular, local paths have no prefix, and if the path comes - /// from an extern crate, start with the path to the `extern - /// crate` declaration. - Local, - - /// Always prepend the crate name to the path, forming an absolute - /// path from within a given set of crates. - Absolute, -} +struct AbsolutePathPrinter; + +impl ItemPathPrinter for AbsolutePathPrinter { + type Path = String; -#[derive(Debug)] -struct LocalPathPrinter { - root_mode: RootMode, + fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { + cx.tcx.original_crate_name(cnum).to_string() + } + fn path_impl(_cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + text.to_string() + } + fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + if !path.is_empty() { + path.push_str("::"); + } + path.push_str(text); + path + } } +struct LocalPathPrinter; + impl LocalPathPrinter { - fn new(root_mode: RootMode) -> LocalPathPrinter { - LocalPathPrinter { - root_mode, + /// If possible, this returns a global path resolving to `def_id` that is visible + /// from at least one local module and returns true. If the crate defining `def_id` is + /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. + fn try_print_visible_item_path( + cx: &mut PrintCx<'_, '_, '_>, + def_id: DefId, + ) -> Option<::Path> { + debug!("try_print_visible_item_path: def_id={:?}", def_id); + + // If `def_id` is a direct or injected extern crate, return the + // path to the crate followed by the path to the item within the crate. + if def_id.index == CRATE_DEF_INDEX { + let cnum = def_id.krate; + + if cnum == LOCAL_CRATE { + return Some(Self::path_crate(cx, cnum)); + } + + // In local mode, when we encounter a crate other than + // LOCAL_CRATE, execution proceeds in one of two ways: + // + // 1. for a direct dependency, where user added an + // `extern crate` manually, we put the `extern + // crate` as the parent. So you wind up with + // something relative to the current crate. + // 2. for an extern inferred from a path or an indirect crate, + // where there is no explicit `extern crate`, we just prepend + // the crate name. + match *cx.tcx.extern_crate(def_id) { + Some(ExternCrate { + src: ExternCrateSource::Extern(def_id), + direct: true, + span, + .. + }) => { + debug!("try_print_visible_item_path: def_id={:?}", def_id); + let path = if !span.is_dummy() { + Self::print_item_path(cx, def_id) + } else { + Self::path_crate(cx, cnum) + }; + return Some(path); + } + None => { + return Some(Self::path_crate(cx, cnum)); + } + _ => {}, + } } + + if def_id.is_local() { + return None; + } + + let visible_parent_map = cx.tcx.visible_parent_map(LOCAL_CRATE); + + let mut cur_def_key = cx.tcx.def_key(def_id); + debug!("try_print_visible_item_path: cur_def_key={:?}", cur_def_key); + + // For a UnitStruct or TupleStruct we want the name of its parent rather than . + if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { + let parent = DefId { + krate: def_id.krate, + index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), + }; + + cur_def_key = cx.tcx.def_key(parent); + } + + let visible_parent = visible_parent_map.get(&def_id).cloned()?; + let path = Self::try_print_visible_item_path(cx, visible_parent)?; + let actual_parent = cx.tcx.parent(def_id); + + let data = cur_def_key.disambiguated_data.data; + debug!( + "try_print_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", + data, visible_parent, actual_parent, + ); + + let symbol = match data { + // In order to output a path that could actually be imported (valid and visible), + // we need to handle re-exports correctly. + // + // For example, take `std::os::unix::process::CommandExt`, this trait is actually + // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). + // + // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is + // private so the "true" path to `CommandExt` isn't accessible. + // + // In this case, the `visible_parent_map` will look something like this: + // + // (child) -> (parent) + // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` + // `std::sys::unix::ext::process` -> `std::sys::unix::ext` + // `std::sys::unix::ext` -> `std::os` + // + // This is correct, as the visible parent of `std::sys::unix::ext` is in fact + // `std::os`. + // + // When printing the path to `CommandExt` and looking at the `cur_def_key` that + // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go + // to the parent - resulting in a mangled path like + // `std::os::ext::process::CommandExt`. + // + // Instead, we must detect that there was a re-export and instead print `unix` + // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To + // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with + // the visible parent (`std::os`). If these do not match, then we iterate over + // the children of the visible parent (as was done when computing + // `visible_parent_map`), looking for the specific child we currently have and then + // have access to the re-exported name. + DefPathData::Module(actual_name) | + DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { + cx.tcx.item_children(visible_parent) + .iter() + .find(|child| child.def.def_id() == def_id) + .map(|child| child.ident.as_str()) + .unwrap_or_else(|| actual_name.as_str()) + } + _ => { + data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { + // Re-exported `extern crate` (#43189). + if let DefPathData::CrateRoot = data { + cx.tcx.original_crate_name(def_id.krate).as_str() + } else { + Symbol::intern("").as_str() + } + }) + }, + }; + debug!("try_print_visible_item_path: symbol={:?}", symbol); + Some(Self::path_append(path, &symbol)) } } impl ItemPathPrinter for LocalPathPrinter { type Path = String; - fn root_mode(&self) -> RootMode { - self.root_mode + fn print_item_path(cx: &mut PrintCx<'_, '_, '_>, def_id: DefId) -> Self::Path { + Self::try_print_visible_item_path(cx, def_id) + .unwrap_or_else(|| cx.default_print_item_path::(def_id)) } - fn path_crate(&self, name: Option<&str>) -> Self::Path { - name.unwrap_or("").to_string() + fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { + if cnum == LOCAL_CRATE { + if cx.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + return keywords::Crate.name().to_string(); + } + } + String::new() + } else { + cx.tcx.crate_name(cnum).to_string() + } } - fn path_impl(&self, text: &str) -> Self::Path { + fn path_impl(_cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { text.to_string() } - fn path_append(&self, mut path: Self::Path, text: &str) -> Self::Path { + fn path_append(mut path: Self::Path, text: &str) -> Self::Path { if !path.is_empty() { path.push_str("::"); } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index a9fffa2ee87b1..81101740a4cc9 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -22,7 +22,7 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } pub struct PrintCx<'a, 'gcx, 'tcx> { - pub(crate) tcx: TyCtxt<'a, 'gcx, 'tcx>, + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, @@ -32,18 +32,20 @@ pub struct PrintCx<'a, 'gcx, 'tcx> { } impl PrintCx<'a, 'gcx, 'tcx> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { + PrintCx { + tcx, + is_debug: false, + is_verbose: tcx.sess.verbose(), + identify_regions: tcx.sess.opts.debugging_opts.identify_regions, + used_region_names: None, + region_index: 0, + binder_depth: 0, + } + } + pub(crate) fn with(f: impl FnOnce(PrintCx<'_, '_, '_>) -> R) -> R { - ty::tls::with(|tcx| { - f(PrintCx { - tcx, - is_debug: false, - is_verbose: tcx.sess.verbose(), - identify_regions: tcx.sess.opts.debugging_opts.identify_regions, - used_region_names: None, - region_index: 0, - binder_depth: 0, - }) - }) + ty::tls::with(|tcx| f(PrintCx::new(tcx))) } pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx> diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 13f8e13c3288d..56ef15b12a0a9 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -87,12 +87,13 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::item_path::{self, ItemPathPrinter, RootMode}; +use rustc::ty::item_path::{self, ItemPathPrinter}; +use rustc::ty::print::PrintCx; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -224,7 +225,8 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { item_path::with_forced_absolute_paths(|| { - tcx.push_item_path(&mut SymbolPath::new(tcx), def_id).into_interned() + let mut cx = PrintCx::new(tcx); + SymbolPathPrinter::print_item_path(&mut cx, def_id).into_interned() }) } @@ -394,29 +396,22 @@ impl SymbolPath { } } -#[derive(Debug)] struct SymbolPathPrinter; impl ItemPathPrinter for SymbolPathPrinter { type Path = SymbolPath; - fn root_mode(&self) ->RootMode { - RootMode::Absolute - } - - fn path_crate(&self, name: Option<&str>) -> Self::Path { - let mut path = SymbolPath::new(); - if let Some(name) = name { - path.push(name); - } + fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { + let mut path = SymbolPath::new(cx.tcx); + path.push(&cx.tcx.original_crate_name(cnum).as_str()); path } - fn path_impl(&self, text: &str) -> Self::Path { - let mut path = SymbolPath::new(); + fn path_impl(cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + let mut path = SymbolPath::new(cx.tcx); path.push(text); path } - fn path_append(&self, mut path: Self::Path, text: &str) -> Self::Path { + fn path_append(mut path: Self::Path, text: &str) -> Self::Path { path.push(text); path } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index af40e417d6108..ed7f1bbe7e6ac 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4225,30 +4225,33 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { pub fn get_path_for_type(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path where F: Fn(DefId) -> Def { - #[derive(Debug)] - struct AbsolutePathBuffer { - names: Vec, - } + use rustc::ty::item_path::ItemPathPrinter; + use rustc::ty::print::PrintCx; - impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer { - fn root_mode(&self) -> &ty::item_path::RootMode { - const ABSOLUTE: &'static ty::item_path::RootMode = &ty::item_path::RootMode::Absolute; - ABSOLUTE - } + struct AbsolutePathPrinter; + + impl ItemPathPrinter for AbsolutePathPrinter { + type Path = Vec; - fn push(&mut self, text: &str) { - self.names.push(text.to_owned()); + fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { + vec![cx.tcx.original_crate_name(cnum).to_string()] + } + fn path_impl(_: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + vec![text.to_string()] + } + fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + path.push(text.to_string()); + path } } - let mut apb = AbsolutePathBuffer { names: vec![] }; - - tcx.push_item_path(&mut apb, def_id); + let mut cx = PrintCx::new(tcx); + let names = AbsolutePathPrinter::print_item_path(&mut cx, def_id); hir::Path { span: DUMMY_SP, def: def_ctor(def_id), - segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment { + segments: hir::HirVec::from_vec(names.iter().map(|s| hir::PathSegment { ident: ast::Ident::from_str(&s), hir_id: None, def: None, From 329b8ca8180ef8aa7314bd0bff9d9cd61f8dad40 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 10 Dec 2018 17:36:24 +0200 Subject: [PATCH 093/157] rustc: always rely on '_ to be not printed by ty::Region itself. --- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/ty/structural_impls.rs | 1 + src/librustc/util/ppaux.rs | 127 ++++++++---------- src/test/ui/issues/issue-17905-2.stderr | 4 +- .../escape-argument-callee.stderr | 2 +- ...pagate-approximated-fail-no-postdom.stderr | 4 +- ...ail-to-approximate-longer-no-bounds.stderr | 4 +- ...-to-approximate-longer-wrong-bounds.stderr | 4 +- 8 files changed, 69 insertions(+), 79 deletions(-) diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index a2924cb993fbf..69d5492c0f450 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< w.push('<'); w.push_str(&substs.iter() .map(|k| k.to_string()) - .filter(|k| &k[..] != "'_") + .filter(|k| !k.is_empty()) .collect::>().join(", ")); w.push('>'); } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index a19eb1d9545a2..43ab32237dea5 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -55,6 +55,7 @@ CloneTypeFoldableAndLiftImpls! { crate::ty::IntVarValue, crate::ty::ParamConst, crate::ty::ParamTy, + crate::ty::RegionVid, crate::ty::UniverseIndex, crate::ty::Variance, ::syntax_pos::Span, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6667d37873310..2a03f32fdccdf 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -120,17 +120,6 @@ impl RegionHighlightMode { Self::highlighting_region(&ty::ReVar(vid), number, op) } - /// Returns `true` if any placeholders are highlighted, and `false` otherwise. - fn any_region_vids_highlighted(&self) -> bool { - Self::get() - .highlight_regions - .iter() - .any(|h| match h { - Some((ty::ReVar(_), _)) => true, - _ => false, - }) - } - /// Returns `Some(n)` with the number to use for the given region, if any. fn region_highlighted(&self, region: ty::Region<'_>) -> Option { Self::get() @@ -163,17 +152,6 @@ impl RegionHighlightMode { ) } - /// Returns `true` if any placeholders are highlighted, and `false` otherwise. - pub fn any_placeholders_highlighted(&self) -> bool { - Self::get() - .highlight_regions - .iter() - .any(|h| match h { - Some((ty::RePlaceholder(_), _)) => true, - _ => false, - }) - } - /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`". pub fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { self.region_highlighted(&ty::RePlaceholder(p)) @@ -421,7 +399,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { if self.is_verbose { write!(f, "{:?}", region)?; } else { - let s = region.to_string(); + let s = region.print_display_to_string(self); if s.is_empty() { // This happens when the value of the region // parameter is not easily serialized. This may be @@ -720,19 +698,20 @@ define_print! { return self.print_debug(f, cx); } - if let Some((region, counter)) = RegionHighlightMode::get().highlight_bound_region { - if *self == region { - return match *self { - BrNamed(_, name) => write!(f, "{}", name), - BrAnon(_) | BrFresh(_) | BrEnv => write!(f, "'{}", counter) - }; + if let BrNamed(_, name) = *self { + if name != "" && name != "'_" { + return write!(f, "{}", name); } } - match *self { - BrNamed(_, name) => write!(f, "{}", name), - BrAnon(_) | BrFresh(_) | BrEnv => Ok(()) + let highlight = RegionHighlightMode::get(); + if let Some((region, counter)) = highlight.highlight_bound_region { + if *self == region { + return write!(f, "'{}", counter); + } } + + Ok(()) } debug { return match *self { @@ -757,12 +736,10 @@ define_print! { let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.placeholder_highlight(*self) { - write!(f, "'{}", counter) - } else if highlight.any_placeholders_highlighted() { - write!(f, "'_") - } else { - write!(f, "{}", self.name) + return write!(f, "'{}", counter); } + + write!(f, "{}", self.name) } } } @@ -785,7 +762,11 @@ define_print! { // `explain_region()` or `note_and_explain_region()`. match *self { ty::ReEarlyBound(ref data) => { - write!(f, "{}", data.name) + if data.name != "'_" { + write!(f, "{}", data.name) + } else { + Ok(()) + } } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { @@ -812,14 +793,11 @@ define_print! { ), } } + ty::ReVar(region_vid) if cx.identify_regions => { + write!(f, "{:?}", region_vid) + } ty::ReVar(region_vid) => { - if RegionHighlightMode::get().any_region_vids_highlighted() { - write!(f, "{:?}", region_vid) - } else if cx.identify_regions { - write!(f, "'{}rv", region_vid.index()) - } else { - Ok(()) - } + write!(f, "{}", region_vid) } ty::ReScope(_) | ty::ReErased => Ok(()), @@ -938,15 +916,30 @@ impl fmt::Debug for ty::FloatVid { } } -impl fmt::Debug for ty::RegionVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(counter) = RegionHighlightMode::get().region_highlighted(&ty::ReVar(*self)) { - return write!(f, "'{:?}", counter); - } else if RegionHighlightMode::get().any_region_vids_highlighted() { - return write!(f, "'_"); +define_print! { + () ty::RegionVid, (self, f, cx) { + display { + if cx.is_verbose { + return self.print_debug(f, cx); + } + + let highlight = RegionHighlightMode::get(); + if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { + return write!(f, "'{:?}", counter); + } + + Ok(()) } + debug { + // HACK(eddyb) this is duplicated from `display` printing, + // to keep NLL borrowck working even with `-Zverbose`. + let highlight = RegionHighlightMode::get(); + if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { + return write!(f, "'{:?}", counter); + } - write!(f, "'_#{}r", self.index()) + write!(f, "'_#{}r", self.index()) + } } } @@ -954,16 +947,15 @@ define_print! { () ty::InferTy, (self, f, cx) { display { if cx.is_verbose { - print!(f, cx, print_debug(self)) - } else { - match *self { - ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) => write!(f, "{}", "{integer}"), - ty::FloatVar(_) => write!(f, "{}", "{float}"), - ty::FreshTy(v) => write!(f, "FreshTy({})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) - } + return self.print_debug(f, cx); + } + match *self { + ty::TyVar(_) => write!(f, "_"), + ty::IntVar(_) => write!(f, "{}", "{integer}"), + ty::FloatVar(_) => write!(f, "{}", "{float}"), + ty::FreshTy(v) => write!(f, "FreshTy({})", v), + ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), + ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) } } debug { @@ -1061,12 +1053,9 @@ define_print! { } Ref(r, ty, mutbl) => { write!(f, "&")?; - let s = r.print_to_string(cx); - if s != "'_" { - write!(f, "{}", s)?; - if !s.is_empty() { - write!(f, " ")?; - } + let s = r.print_display_to_string(cx); + if !s.is_empty() { + write!(f, "{} ", s)?; } ty::TypeAndMut { ty, mutbl }.print(f, cx) } @@ -1112,7 +1101,7 @@ define_print! { } Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()), Dynamic(data, r) => { - let r = r.print_to_string(cx); + let r = r.print_display_to_string(cx); if !r.is_empty() { write!(f, "(")?; } diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr index f185f49b9b922..e3909e0c1253f 100644 --- a/src/test/ui/issues/issue-17905-2.stderr +++ b/src/test/ui/issues/issue-17905-2.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched method receiver LL | fn say(self: &Pair<&str, isize>) { | ^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Pair<&'_ str, _>` + = note: expected type `Pair<&str, _>` found type `Pair<&str, _>` note: the anonymous lifetime #2 defined on the method body at 8:5... --> $DIR/issue-17905-2.rs:8:5 @@ -27,7 +27,7 @@ error[E0308]: mismatched method receiver LL | fn say(self: &Pair<&str, isize>) { | ^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Pair<&'_ str, _>` + = note: expected type `Pair<&str, _>` found type `Pair<&str, _>` note: the lifetime '_ as defined on the impl at 5:5... --> $DIR/issue-17905-2.rs:5:5 diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 8e407070342cf..46de13dbbbd9b 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -16,7 +16,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | - - ^^^^^^ assignment requires that `'1` must outlive `'2` | | | | | has type `&'1 i32` - | has type `&mut &'2 i32` + | has type `&'_#2r mut &'2 i32` note: No external requirements --> $DIR/escape-argument-callee.rs:20:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 067bd08220df4..7eb4d96fc5f75 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- has type `std::cell::Cell<&'2 &u32>` + | ---------- ---------- has type `std::cell::Cell<&'2 &'_#3r u32>` | | - | has type `std::cell::Cell<&&'1 u32>` + | has type `std::cell::Cell<&'_#1r &'1 u32>` ... LL | demand_y(x, y, p) | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 5cf37bedb8853..f8b6bfa003b32 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | --------- - has type `&std::cell::Cell<&'1 u32>` + | --------- - has type `&'_#7r std::cell::Cell<&'1 u32>` | | - | has type `&std::cell::Cell<&'2 &u32>` + | has type `&'_#5r std::cell::Cell<&'2 &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 671a8b9a93575..7e7429405fa06 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -20,9 +20,9 @@ error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ---------- ---------- has type `&std::cell::Cell<&'2 &u32>` + | ---------- ---------- has type `&'_#8r std::cell::Cell<&'2 &'_#2r u32>` | | - | has type `&std::cell::Cell<&'1 &u32>` + | has type `&'_#6r std::cell::Cell<&'1 &'_#1r u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` From 732b71a1ba4de6a3ecaae5fe1c4e916a7dae33a0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Dec 2018 09:47:45 +0200 Subject: [PATCH 094/157] rustc: add a ty::RegionKind::display_outputs_anything method to avoid printing to a string. --- src/librustc/ty/print.rs | 15 ---- src/librustc/util/ppaux.rs | 142 +++++++++++++++++++++++++++++++------ 2 files changed, 120 insertions(+), 37 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 81101740a4cc9..7085a3beb1ceb 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -59,11 +59,6 @@ impl PrintCx<'a, 'gcx, 'tcx> { pub trait Print<'tcx> { fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { - let mut result = String::new(); - let _ = self.print(&mut result, cx); - result - } fn print_display( &self, f: &mut F, @@ -75,11 +70,6 @@ pub trait Print<'tcx> { cx.is_debug = old_debug; result } - fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { - let mut result = String::new(); - let _ = self.print_display(&mut result, cx); - result - } fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; @@ -87,9 +77,4 @@ pub trait Print<'tcx> { cx.is_debug = old_debug; result } - fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { - let mut result = String::new(); - let _ = self.print_debug(&mut result, cx); - result - } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2a03f32fdccdf..a0feeae0a0cc8 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -396,20 +396,15 @@ impl PrintCx<'a, 'gcx, 'tcx> { continue; } start_or_continue(f, start, ", ")?; - if self.is_verbose { - write!(f, "{:?}", region)?; + if !region.display_outputs_anything(self) { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + write!(f, "'_")?; } else { - let s = region.print_display_to_string(self); - if s.is_empty() { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(f, "'_")?; - } else { - write!(f, "{}", s)?; - } + region.print_display(f, self)?; } } UnpackedKind::Type(ty) => { @@ -727,6 +722,32 @@ define_print! { } } +// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) +// +// NB: this must be kept in sync with the printing logic above. +impl ty::BoundRegion { + fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + if cx.is_verbose { + return true; + } + + if let BrNamed(_, name) = *self { + if name != "" && name != "'_" { + return true; + } + } + + let highlight = RegionHighlightMode::get(); + if let Some((region, _)) = highlight.highlight_bound_region { + if *self == region { + return true; + } + } + + false + } +} + define_print! { () ty::PlaceholderRegion, (self, f, cx) { display { @@ -744,6 +765,24 @@ define_print! { } } +// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) +// +// NB: this must be kept in sync with the printing logic above. +impl ty::PlaceholderRegion { + fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + if cx.is_verbose { + return true; + } + + let highlight = RegionHighlightMode::get(); + if highlight.placeholder_highlight(*self).is_some() { + return true; + } + + self.name.display_outputs_anything(cx) + } +} + define_print! { () ty::RegionKind, (self, f, cx) { display { @@ -851,6 +890,49 @@ define_print! { } } +// HACK(eddyb) Trying to print a lifetime might not print anything, which +// may need special handling in the caller (of `ty::RegionKind::print`). +// To avoid printing to a temporary string, the `display_outputs_anything` +// method can instead be used to determine this, ahead of time. +// +// NB: this must be kept in sync with the printing logic above. +impl ty::RegionKind { + fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + if cx.is_verbose { + return true; + } + + if RegionHighlightMode::get().region_highlighted(self).is_some() { + return true; + } + + match *self { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { + br.display_outputs_anything(cx) + } + + ty::RePlaceholder(p) => p.display_outputs_anything(cx), + + ty::ReScope(_) | + ty::ReVar(_) if cx.identify_regions => true, + + ty::ReVar(region_vid) => region_vid.display_outputs_anything(cx), + + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } + } +} + define_print! { () ty::FreeRegion, (self, f, cx) { debug { @@ -943,6 +1025,24 @@ define_print! { } } +// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) +// +// NB: this must be kept in sync with the printing logic above. +impl ty::RegionVid { + fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + if cx.is_verbose { + return true; + } + + let highlight = RegionHighlightMode::get(); + if highlight.region_highlighted(&ty::ReVar(*self)).is_some() { + return true; + } + + false + } +} + define_print! { () ty::InferTy, (self, f, cx) { display { @@ -1053,9 +1153,8 @@ define_print! { } Ref(r, ty, mutbl) => { write!(f, "&")?; - let s = r.print_display_to_string(cx); - if !s.is_empty() { - write!(f, "{} ", s)?; + if r.display_outputs_anything(cx) { + print!(f, cx, print_display(r), write(" "))?; } ty::TypeAndMut { ty, mutbl }.print(f, cx) } @@ -1101,17 +1200,16 @@ define_print! { } Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()), Dynamic(data, r) => { - let r = r.print_display_to_string(cx); - if !r.is_empty() { + let print_r = r.display_outputs_anything(cx); + if print_r { write!(f, "(")?; } write!(f, "dyn ")?; data.print(f, cx)?; - if !r.is_empty() { - write!(f, " + {})", r) - } else { - Ok(()) + if print_r { + print!(f, cx, write(" + "), print_display(r), write(")"))?; } + Ok(()) } Foreign(def_id) => { cx.parameterized(f, def_id, subst::InternalSubsts::empty(), iter::empty()) From 08d27441ecc96a56e1b0e72c0accbced2ce6a7d3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 10 Dec 2018 16:10:22 +0200 Subject: [PATCH 095/157] rustc: move the formatter into ty::print::PrintCx. --- src/librustc/lib.rs | 1 + src/librustc/mir/mod.rs | 4 +- src/librustc/ty/item_path.rs | 130 ++-- src/librustc/ty/print.rs | 44 +- src/librustc/util/ppaux.rs | 662 ++++++++++----------- src/librustc_codegen_utils/lib.rs | 1 + src/librustc_codegen_utils/symbol_names.rs | 19 +- src/librustdoc/clean/mod.rs | 15 +- src/librustdoc/lib.rs | 1 + 9 files changed, 448 insertions(+), 429 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 681dffc0116e3..53f39d3ac8a37 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -31,6 +31,7 @@ #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(core_intrinsics)] diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index bff07de5bcf33..7d2050a7c68a8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,7 +2369,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - ty::print::PrintCx::with(|cx| { + ty::print::PrintCx::with(ty::print::FmtPrinter { fmt }, |cx| { let region = if cx.is_verbose || cx.identify_regions { let mut region = region.to_string(); if region.len() > 0 { @@ -2380,7 +2380,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { // Do not even print 'static String::new() }; - write!(fmt, "&{}{}{:?}", region, kind_str, place) + write!(cx.printer.fmt, "&{}{}{:?}", region, kind_str, place) }) } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 6f8d0d19103ea..0612401ca25db 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -59,11 +59,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// root, unless with_forced_absolute_paths was used. pub fn item_path_str(self, def_id: DefId) -> String { debug!("item_path_str: def_id={:?}", def_id); - let mut cx = PrintCx::new(self); if FORCE_ABSOLUTE.with(|force| force.get()) { - AbsolutePathPrinter::print_item_path(&mut cx, def_id) + PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id) } else { - LocalPathPrinter::print_item_path(&mut cx, def_id) + PrintCx::new(self, LocalPathPrinter).print_item_path(def_id) } } @@ -76,26 +75,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { debug!("absolute_item_path_str: def_id={:?}", def_id); - let mut cx = PrintCx::new(self); - AbsolutePathPrinter::print_item_path(&mut cx, def_id) + PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id) } } -impl PrintCx<'a, 'gcx, 'tcx> { - pub fn default_print_item_path

(&mut self, def_id: DefId) -> P::Path - where P: ItemPathPrinter - { +impl PrintCx<'a, 'gcx, 'tcx, P> { + pub fn default_print_item_path(&mut self, def_id: DefId) -> P::Path { debug!("default_print_item_path: def_id={:?}", def_id); let key = self.tcx.def_key(def_id); debug!("default_print_item_path: key={:?}", key); match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); - P::path_crate(self, def_id.krate) + self.path_crate(def_id.krate) } DefPathData::Impl => { - self.default_print_impl_path::

(def_id) + self.default_print_impl_path(def_id) } // Unclear if there is any value in distinguishing these. @@ -121,20 +117,18 @@ impl PrintCx<'a, 'gcx, 'tcx> { data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { let parent_did = self.tcx.parent_def_id(def_id).unwrap(); - let path = P::print_item_path(self, parent_did); - P::path_append(path, &data.as_interned_str().as_symbol().as_str()) + let path = self.print_item_path(parent_did); + self.path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); - P::print_item_path(self, parent_def_id) + self.print_item_path(parent_def_id) } } } - fn default_print_impl_path

(&mut self, impl_def_id: DefId) -> P::Path - where P: ItemPathPrinter - { + fn default_print_impl_path(&mut self, impl_def_id: DefId) -> P::Path { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); @@ -147,7 +141,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { }; if !use_types { - return self.default_print_impl_path_fallback::

(impl_def_id); + return self.default_print_impl_path_fallback(impl_def_id); } // Decide whether to print the parent path for the impl. @@ -171,11 +165,11 @@ impl PrintCx<'a, 'gcx, 'tcx> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = P::print_item_path(self, parent_def_id); + let path = self.print_item_path(parent_def_id); if let Some(trait_ref) = impl_trait_ref { - return P::path_append(path, &format!("", trait_ref, self_ty)); + return self.path_append(path, &format!("", trait_ref, self_ty)); } else { - return P::path_append(path, &format!("", self_ty)); + return self.path_append(path, &format!("", self_ty)); } } @@ -184,7 +178,7 @@ impl PrintCx<'a, 'gcx, 'tcx> { if let Some(trait_ref) = impl_trait_ref { // Trait impls. - return P::path_impl(self, &format!("<{} as {}>", self_ty, trait_ref)); + return self.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); } // Inherent impls. Try to print `Foo::bar` for an inherent @@ -194,13 +188,13 @@ impl PrintCx<'a, 'gcx, 'tcx> { ty::Adt(adt_def, substs) => { // FIXME(eddyb) always print without <> here. if substs.types().next().is_none() { // ignore regions - P::print_item_path(self, adt_def.did) + self.print_item_path(adt_def.did) } else { - P::path_impl(self, &format!("<{}>", self_ty)) + self.path_impl(&format!("<{}>", self_ty)) } } - ty::Foreign(did) => P::print_item_path(self, did), + ty::Foreign(did) => self.print_item_path(did), ty::Bool | ty::Char | @@ -208,28 +202,26 @@ impl PrintCx<'a, 'gcx, 'tcx> { ty::Uint(_) | ty::Float(_) | ty::Str => { - P::path_impl(self, &self_ty.to_string()) + self.path_impl(&self_ty.to_string()) } _ => { - P::path_impl(self, &format!("<{}>", self_ty)) + self.path_impl(&format!("<{}>", self_ty)) } } } - fn default_print_impl_path_fallback

(&mut self, impl_def_id: DefId) -> P::Path - where P: ItemPathPrinter - { + fn default_print_impl_path_fallback(&mut self, impl_def_id: DefId) -> P::Path { // If no type info is available, fall back to // pretty printing some span information. This should // only occur very early in the compiler pipeline. // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); - let path = P::print_item_path(self, parent_def_id); + let path = self.print_item_path(parent_def_id); let hir_id = self.tcx.hir().as_local_hir_id(impl_def_id).unwrap(); let item = self.tcx.hir().expect_item_by_hir_id(hir_id); let span_str = self.tcx.sess.source_map().span_to_string(item.span); - P::path_append(path, &format!("", span_str)) + self.path_append(path, &format!("", span_str)) } } @@ -296,13 +288,17 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { pub trait ItemPathPrinter: Sized { type Path; - fn print_item_path(cx: &mut PrintCx<'_, '_, '_>, def_id: DefId) -> Self::Path { - cx.default_print_item_path::(def_id) + fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path { + self.default_print_item_path(def_id) } - fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path; - fn path_impl(cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path; - fn path_append(path: Self::Path, text: &str) -> Self::Path; + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + path: Self::Path, + text: &str, + ) -> Self::Path; } struct AbsolutePathPrinter; @@ -310,13 +306,17 @@ struct AbsolutePathPrinter; impl ItemPathPrinter for AbsolutePathPrinter { type Path = String; - fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { - cx.tcx.original_crate_name(cnum).to_string() + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + self.tcx.original_crate_name(cnum).to_string() } - fn path_impl(_cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { text.to_string() } - fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { if !path.is_empty() { path.push_str("::"); } @@ -332,7 +332,7 @@ impl LocalPathPrinter { /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. fn try_print_visible_item_path( - cx: &mut PrintCx<'_, '_, '_>, + self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId, ) -> Option<::Path> { debug!("try_print_visible_item_path: def_id={:?}", def_id); @@ -343,7 +343,7 @@ impl LocalPathPrinter { let cnum = def_id.krate; if cnum == LOCAL_CRATE { - return Some(Self::path_crate(cx, cnum)); + return Some(self.path_crate(cnum)); } // In local mode, when we encounter a crate other than @@ -356,7 +356,7 @@ impl LocalPathPrinter { // 2. for an extern inferred from a path or an indirect crate, // where there is no explicit `extern crate`, we just prepend // the crate name. - match *cx.tcx.extern_crate(def_id) { + match *self.tcx.extern_crate(def_id) { Some(ExternCrate { src: ExternCrateSource::Extern(def_id), direct: true, @@ -365,14 +365,14 @@ impl LocalPathPrinter { }) => { debug!("try_print_visible_item_path: def_id={:?}", def_id); let path = if !span.is_dummy() { - Self::print_item_path(cx, def_id) + self.print_item_path(def_id) } else { - Self::path_crate(cx, cnum) + self.path_crate(cnum) }; return Some(path); } None => { - return Some(Self::path_crate(cx, cnum)); + return Some(self.path_crate(cnum)); } _ => {}, } @@ -382,9 +382,9 @@ impl LocalPathPrinter { return None; } - let visible_parent_map = cx.tcx.visible_parent_map(LOCAL_CRATE); + let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); - let mut cur_def_key = cx.tcx.def_key(def_id); + let mut cur_def_key = self.tcx.def_key(def_id); debug!("try_print_visible_item_path: cur_def_key={:?}", cur_def_key); // For a UnitStruct or TupleStruct we want the name of its parent rather than . @@ -394,12 +394,12 @@ impl LocalPathPrinter { index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), }; - cur_def_key = cx.tcx.def_key(parent); + cur_def_key = self.tcx.def_key(parent); } let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = Self::try_print_visible_item_path(cx, visible_parent)?; - let actual_parent = cx.tcx.parent(def_id); + let path = self.try_print_visible_item_path(visible_parent)?; + let actual_parent = self.tcx.parent(def_id); let data = cur_def_key.disambiguated_data.data; debug!( @@ -441,7 +441,7 @@ impl LocalPathPrinter { // have access to the re-exported name. DefPathData::Module(actual_name) | DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - cx.tcx.item_children(visible_parent) + self.tcx.item_children(visible_parent) .iter() .find(|child| child.def.def_id() == def_id) .map(|child| child.ident.as_str()) @@ -451,7 +451,7 @@ impl LocalPathPrinter { data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { // Re-exported `extern crate` (#43189). if let DefPathData::CrateRoot = data { - cx.tcx.original_crate_name(def_id.krate).as_str() + self.tcx.original_crate_name(def_id.krate).as_str() } else { Symbol::intern("").as_str() } @@ -459,21 +459,21 @@ impl LocalPathPrinter { }, }; debug!("try_print_visible_item_path: symbol={:?}", symbol); - Some(Self::path_append(path, &symbol)) + Some(self.path_append(path, &symbol)) } } impl ItemPathPrinter for LocalPathPrinter { type Path = String; - fn print_item_path(cx: &mut PrintCx<'_, '_, '_>, def_id: DefId) -> Self::Path { - Self::try_print_visible_item_path(cx, def_id) - .unwrap_or_else(|| cx.default_print_item_path::(def_id)) + fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path { + self.try_print_visible_item_path(def_id) + .unwrap_or_else(|| self.default_print_item_path(def_id)) } - fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { if cnum == LOCAL_CRATE { - if cx.tcx.sess.rust_2018() { + if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { return keywords::Crate.name().to_string(); @@ -481,13 +481,17 @@ impl ItemPathPrinter for LocalPathPrinter { } String::new() } else { - cx.tcx.crate_name(cnum).to_string() + self.tcx.crate_name(cnum).to_string() } } - fn path_impl(_cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { text.to_string() } - fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { if !path.is_empty() { path.push_str("::"); } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 7085a3beb1ceb..a1d93bc4140cc 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashSet; use syntax::symbol::InternedString; use std::fmt; +use std::ops::Deref; // FIXME(eddyb) this module uses `pub(crate)` for things used only // from `ppaux` - when that is removed, they can be re-privatized. @@ -21,8 +22,9 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } } -pub struct PrintCx<'a, 'gcx, 'tcx> { +pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, + pub printer: P, pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, @@ -31,10 +33,20 @@ pub struct PrintCx<'a, 'gcx, 'tcx> { pub(crate) binder_depth: usize, } -impl PrintCx<'a, 'gcx, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { +// HACK(eddyb) this is solely for `self: &mut PrintCx`, e.g. to +// implement traits on the printer and call the methods on the context. +impl

Deref for PrintCx<'_, '_, '_, P> { + type Target = P; + fn deref(&self) -> &P { + &self.printer + } +} + +impl

PrintCx<'a, 'gcx, 'tcx, P> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, printer: P) -> Self { PrintCx { tcx, + printer, is_debug: false, is_verbose: tcx.sess.verbose(), identify_regions: tcx.sess.opts.debugging_opts.identify_regions, @@ -44,8 +56,8 @@ impl PrintCx<'a, 'gcx, 'tcx> { } } - pub(crate) fn with(f: impl FnOnce(PrintCx<'_, '_, '_>) -> R) -> R { - ty::tls::with(|tcx| f(PrintCx::new(tcx))) + pub(crate) fn with(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { + ty::tls::with(|tcx| f(PrintCx::new(tcx, printer))) } pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx> @@ -57,24 +69,26 @@ impl PrintCx<'a, 'gcx, 'tcx> { } } -pub trait Print<'tcx> { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result; - fn print_display( - &self, - f: &mut F, - cx: &mut PrintCx<'_, '_, 'tcx>, - ) -> fmt::Result { +pub trait Print<'tcx, P> { + type Output; + + fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output; + fn print_display(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { let old_debug = cx.is_debug; cx.is_debug = false; - let result = self.print(f, cx); + let result = self.print(cx); cx.is_debug = old_debug; result } - fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { + fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { let old_debug = cx.is_debug; cx.is_debug = true; - let result = self.print(f, cx); + let result = self.print(cx); cx.is_debug = old_debug; result } } + +pub struct FmtPrinter { + pub fmt: F, +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a0feeae0a0cc8..780ff8a61e41c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,7 +9,7 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, ParamConst, Ty, TypeFoldable}; -use crate::ty::print::{PrintCx, Print}; +use crate::ty::print::{FmtPrinter, PrintCx, Print}; use crate::mir::interpret::ConstValue; use std::cell::Cell; @@ -161,8 +161,8 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|mut cx| { - $with(&cx.tcx.lift(self).expect("could not lift for printing"), f, &mut cx) + PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + $with(&cx.tcx.lift(self).expect("could not lift for printing"), &mut cx) }) } }; @@ -191,25 +191,19 @@ macro_rules! gen_display_debug { ( $generic:tt $target:ty, $t:ident no ) => {}; } macro_rules! gen_print_impl { - ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl<$($x)+> Print<'tcx> for $target { - fn print( - &$self, - $f: &mut F, - $cx: &mut PrintCx<'_, '_, 'tcx>, - ) -> fmt::Result { + ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { + impl<$($x)+, F: fmt::Write> Print<'tcx, FmtPrinter> for $target { + type Output = fmt::Result; + fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter>) -> fmt::Result { if $cx.is_debug $dbg else $disp } } }; - ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { - impl Print<'tcx> for $target { - fn print( - &$self, - $f: &mut F, - $cx: &mut PrintCx<'_, '_, 'tcx>, - ) -> fmt::Result { + ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { + impl Print<'tcx, FmtPrinter> for $target { + type Output = fmt::Result; + fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter>) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -238,9 +232,9 @@ macro_rules! define_print { } yes $dbg } }; ( $generic:tt $target:ty, - ($self:ident, $f:ident, $cx:ident) { display $disp:block } ) => { - gen_print_impl! { $generic $target, ($self, $f, $cx) yes $disp no { - write!($f, "{:?}", $self) + ($self:ident, $cx:ident) { display $disp:block } ) => { + gen_print_impl! { $generic $target, ($self, $cx) yes $disp no { + write!($cx.printer.fmt, "{:?}", $self) } } }; } @@ -250,48 +244,47 @@ macro_rules! define_print_multi { }; } macro_rules! print_inner { - ( $f:expr, $cx:expr, write ($($data:expr),+) ) => { - write!($f, $($data),+) + ( $cx:expr, write ($($data:expr),+) ) => { + write!($cx.printer.fmt, $($data),+) }; - ( $f:expr, $cx:expr, $kind:ident ($data:expr) ) => { - $data.$kind($f, $cx) + ( $cx:expr, $kind:ident ($data:expr) ) => { + $data.$kind($cx) }; } macro_rules! print { - ( $f:expr, $cx:expr $(, $kind:ident $data:tt)+ ) => { - Ok(())$(.and_then(|_| print_inner!($f, $cx, $kind $data)))+ + ( $cx:expr $(, $kind:ident $data:tt)+ ) => { + Ok(())$(.and_then(|_| print_inner!($cx, $kind $data)))+ }; } -impl PrintCx<'a, 'gcx, 'tcx> { - fn fn_sig(&mut self, - f: &mut F, - inputs: &[Ty<'tcx>], - c_variadic: bool, - output: Ty<'tcx>) - -> fmt::Result { - write!(f, "(")?; +impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { + fn fn_sig( + &mut self, + inputs: &[Ty<'tcx>], + c_variadic: bool, + output: Ty<'tcx>, + ) -> fmt::Result { + print!(self, write("("))?; let mut inputs = inputs.iter(); if let Some(&ty) = inputs.next() { - print!(f, self, print_display(ty))?; + print!(self, print_display(ty))?; for &ty in inputs { - print!(f, self, write(", "), print_display(ty))?; + print!(self, write(", "), print_display(ty))?; } if c_variadic { - write!(f, ", ...")?; + print!(self, write(", ..."))?; } } - write!(f, ")")?; + print!(self, write(")"))?; if !output.is_unit() { - print!(f, self, write(" -> "), print_display(output))?; + print!(self, write(" -> "), print_display(output))?; } Ok(()) } - fn parameterized( + fn parameterized( &mut self, - f: &mut F, mut def_id: DefId, substs: SubstsRef<'tcx>, projections: impl Iterator>, @@ -321,41 +314,41 @@ impl PrintCx<'a, 'gcx, 'tcx> { let parent_has_own_self = parent_generics.has_self && parent_generics.parent_count == 0; if parent_has_own_self { - print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; + print!(self, write("<"), print_display(substs.type_at(0)), write(" as "))?; } - self.parameterized(f, parent_def_id, substs, iter::empty())?; + self.parameterized(parent_def_id, substs, iter::empty())?; if parent_has_own_self { - write!(f, ">")?; + print!(self, write(">"))?; } - write!(f, "::{}", key.disambiguated_data.data.as_interned_str())?; + print!(self, write("::{}", key.disambiguated_data.data.as_interned_str()))?; } else { // Try to print `impl`s more like how you'd refer to their associated items. if let DefPathData::Impl = key.disambiguated_data.data { if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { // HACK(eddyb) this is in lieu of more specific disambiguation. - print!(f, self, write("{}", self.tcx.item_path_str(def_id)))?; + print!(self, write("{}", self.tcx.item_path_str(def_id)))?; let trait_ref = trait_ref.subst(self.tcx, substs); - print!(f, self, print_debug(trait_ref))?; + print!(self, print_debug(trait_ref))?; } else { let self_ty = self.tcx.type_of(def_id).subst(self.tcx, substs); // FIXME(eddyb) omit the <> where possible. - print!(f, self, write("<"), print(self_ty), write(">"))?; + print!(self, write("<"), print(self_ty), write(">"))?; } return Ok(()); } - print!(f, self, write("{}", self.tcx.item_path_str(def_id)))?; + print!(self, write("{}", self.tcx.item_path_str(def_id)))?; } let mut empty = true; - let mut start_or_continue = |f: &mut F, start: &str, cont: &str| { + let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { if empty { empty = false; - write!(f, "{}", start) + print!(cx, write("{}", start)) } else { - write!(f, "{}", cont) + print!(cx, write("{}", cont)) } }; @@ -395,42 +388,42 @@ impl PrintCx<'a, 'gcx, 'tcx> { if !print_regions { continue; } - start_or_continue(f, start, ", ")?; + start_or_continue(self, start, ", ")?; if !region.display_outputs_anything(self) { // This happens when the value of the region // parameter is not easily serialized. This may be // because the user omitted it in the first place, // or because it refers to some block in the code, // etc. I'm not sure how best to serialize this. - write!(f, "'_")?; + print!(self, write("'_"))?; } else { - region.print_display(f, self)?; + region.print_display(self)?; } } UnpackedKind::Type(ty) => { - start_or_continue(f, start, ", ")?; - ty.print_display(f, self)?; + start_or_continue(self, start, ", ")?; + ty.print_display(self)?; } UnpackedKind::Const(ct) => { - start_or_continue(f, start, ", ")?; - ct.print_display(f, self)?; + start_or_continue(self, start, ", ")?; + ct.print_display(self)?; } } } for projection in projections { - start_or_continue(f, start, ", ")?; - print!(f, self, + start_or_continue(self, start, ", ")?; + print!(self, write("{}=", self.tcx.associated_item(projection.item_def_id).ident), print_display(projection.ty))?; } - start_or_continue(f, "", ">") + start_or_continue(self, "", ">") } - fn in_binder(&mut self, f: &mut F, value: &ty::Binder) -> fmt::Result - where T: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write + fn in_binder(&mut self, value: &ty::Binder) -> fmt::Result + where T: Print<'tcx, FmtPrinter, Output = fmt::Result> + TypeFoldable<'tcx> { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -450,22 +443,22 @@ impl PrintCx<'a, 'gcx, 'tcx> { } let mut empty = true; - let mut start_or_continue = |f: &mut F, start: &str, cont: &str| { + let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { if empty { empty = false; - write!(f, "{}", start) + print!(cx, write("{}", start)) } else { - write!(f, "{}", cont) + print!(cx, write("{}", cont)) } }; let old_region_index = self.region_index; let mut region_index = old_region_index; let new_value = self.tcx.replace_late_bound_regions(value, |br| { - let _ = start_or_continue(f, "for<", ", "); + let _ = start_or_continue(self, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { - let _ = write!(f, "{}", name); + let _ = print!(self, write("{}", name)); br } ty::BrAnon(_) | @@ -478,18 +471,18 @@ impl PrintCx<'a, 'gcx, 'tcx> { break name; } }; - let _ = write!(f, "{}", name); + let _ = print!(self, write("{}", name)); ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name) } }; self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) }).0; - start_or_continue(f, "", "> ")?; + start_or_continue(self, "", "> ")?; // Push current state to gcx, and restore after writing new_value. self.binder_depth += 1; self.region_index = region_index; - let result = new_value.print_display(f, self); + let result = new_value.print_display(self); self.region_index = old_region_index; self.binder_depth -= 1; result @@ -504,20 +497,21 @@ impl PrintCx<'a, 'gcx, 'tcx> { } pub fn parameterized(f: &mut F, did: DefId, substs: SubstsRef<'_>) -> fmt::Result { - PrintCx::with(|mut cx| { + PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.parameterized(f, did, substs, iter::empty()) + cx.parameterized(did, substs, iter::empty()) }) } -impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { - (*self).print(f, cx) +impl<'a, 'tcx, P, T: Print<'tcx, P>> Print<'tcx, P> for &'a T { + type Output = T::Output; + fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { + (*self).print(cx) } } define_print! { - ('tcx) &'tcx ty::List>, (self, f, cx) { + ('tcx) &'tcx ty::List>, (self, cx) { display { // Generate the main trait ref, including associated types. let mut first = true; @@ -530,8 +524,8 @@ define_print! { if let Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - print!(f, cx, write("{}", cx.tcx.item_path_str(principal.def_id)))?; - cx.fn_sig(f, args, false, proj.ty)?; + print!(cx, write("{}", cx.tcx.item_path_str(principal.def_id)))?; + cx.fn_sig(args, false, proj.ty)?; resugared_principal = true; } } @@ -542,7 +536,6 @@ define_print! { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let principal = principal.with_self_ty(cx.tcx, dummy_self); cx.parameterized( - f, principal.def_id, principal.substs, self.projection_bounds(), @@ -567,11 +560,11 @@ define_print! { for auto_trait in auto_traits { if !first { - write!(f, " + ")?; + print!(cx, write(" + "))?; } first = false; - write!(f, "{}", auto_trait)?; + print!(cx, write("{}", auto_trait))?; } Ok(()) @@ -596,16 +589,16 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|cx| { - write!(f, "{}", cx.tcx.item_path_str(self.def_id)) + PrintCx::with(FmtPrinter { fmt: f }, |cx| { + print!(cx, write("{}", cx.tcx.item_path_str(self.def_id))) }) } } impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|cx| { - write!(f, "{}", cx.tcx.item_path_str(self.did)) + PrintCx::with(FmtPrinter { fmt: f }, |cx| { + print!(cx, write("{}", cx.tcx.item_path_str(self.did))) }) } } @@ -620,12 +613,12 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UpvarId({:?};`{}`;{:?})", - self.var_path.hir_id, - PrintCx::with(|cx| { - cx.tcx.hir().name_by_hir_id(self.var_path.hir_id) - }), - self.closure_expr_id) + PrintCx::with(FmtPrinter { fmt: f }, |cx| { + print!(cx, write("UpvarId({:?};`{}`;{:?})", + self.var_path.hir_id, + cx.tcx.hir().name_by_hir_id(self.var_path.hir_id), + self.closure_expr_id)) + }) } } @@ -637,25 +630,25 @@ impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { } define_print! { - ('tcx) &'tcx ty::List>, (self, f, cx) { + ('tcx) &'tcx ty::List>, (self, cx) { display { - write!(f, "{{")?; + print!(cx, write("{{"))?; let mut tys = self.iter(); if let Some(&ty) = tys.next() { - print!(f, cx, print(ty))?; + print!(cx, print(ty))?; for &ty in tys { - print!(f, cx, write(", "), print(ty))?; + print!(cx, write(", "), print(ty))?; } } - write!(f, "}}") + print!(cx, write("}}")) } } } define_print! { - ('tcx) ty::TypeAndMut<'tcx>, (self, f, cx) { + ('tcx) ty::TypeAndMut<'tcx>, (self, cx) { display { - print!(f, cx, + print!(cx, write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), print(self.ty)) } @@ -663,46 +656,46 @@ define_print! { } define_print! { - ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) { + ('tcx) ty::ExistentialTraitRef<'tcx>, (self, cx) { display { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let trait_ref = *ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) .skip_binder(); - cx.parameterized(f, trait_ref.def_id, trait_ref.substs, iter::empty()) + cx.parameterized(trait_ref.def_id, trait_ref.substs, iter::empty()) } debug { - self.print_display(f, cx) + self.print_display(cx) } } } define_print! { - ('tcx) ty::adjustment::Adjustment<'tcx>, (self, f, cx) { + ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) { debug { - print!(f, cx, write("{:?} -> ", self.kind), print(self.target)) + print!(cx, write("{:?} -> ", self.kind), print(self.target)) } } } define_print! { - () ty::BoundRegion, (self, f, cx) { + () ty::BoundRegion, (self, cx) { display { if cx.is_verbose { - return self.print_debug(f, cx); + return self.print_debug(cx); } if let BrNamed(_, name) = *self { if name != "" && name != "'_" { - return write!(f, "{}", name); + return print!(cx, write("{}", name)); } } let highlight = RegionHighlightMode::get(); if let Some((region, counter)) = highlight.highlight_bound_region { if *self == region { - return write!(f, "'{}", counter); + return print!(cx, write("'{}", counter)); } } @@ -710,13 +703,13 @@ define_print! { } debug { return match *self { - BrAnon(n) => write!(f, "BrAnon({:?})", n), - BrFresh(n) => write!(f, "BrFresh({:?})", n), + BrAnon(n) => print!(cx, write("BrAnon({:?})", n)), + BrFresh(n) => print!(cx, write("BrFresh({:?})", n)), BrNamed(did, name) => { - write!(f, "BrNamed({:?}:{:?}, {})", - did.krate, did.index, name) + print!(cx, write("BrNamed({:?}:{:?}, {})", + did.krate, did.index, name)) } - BrEnv => write!(f, "BrEnv"), + BrEnv => print!(cx, write("BrEnv")), }; } } @@ -726,7 +719,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::BoundRegion { - fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { if cx.is_verbose { return true; } @@ -749,18 +742,18 @@ impl ty::BoundRegion { } define_print! { - () ty::PlaceholderRegion, (self, f, cx) { + () ty::PlaceholderRegion, (self, cx) { display { if cx.is_verbose { - return self.print_debug(f, cx); + return self.print_debug(cx); } let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.placeholder_highlight(*self) { - return write!(f, "'{}", counter); + return print!(cx, write("'{}", counter)); } - write!(f, "{}", self.name) + print!(cx, print_display(self.name)) } } } @@ -769,7 +762,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::PlaceholderRegion { - fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { if cx.is_verbose { return true; } @@ -784,15 +777,15 @@ impl ty::PlaceholderRegion { } define_print! { - () ty::RegionKind, (self, f, cx) { + () ty::RegionKind, (self, cx) { display { if cx.is_verbose { - return self.print_debug(f, cx); + return self.print_debug(cx); } // Watch out for region highlights. if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { - return write!(f, "'{:?}", n); + return print!(cx, write("'{:?}", n)); } // These printouts are concise. They do not contain all the information @@ -802,89 +795,88 @@ define_print! { match *self { ty::ReEarlyBound(ref data) => { if data.name != "'_" { - write!(f, "{}", data.name) + print!(cx, write("{}", data.name)) } else { Ok(()) } } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { - write!(f, "{}", br) + print!(cx, print_display(br)) } ty::RePlaceholder(p) => { - write!(f, "{}", p) + print!(cx, print_display(p)) } ty::ReScope(scope) if cx.identify_regions => { match scope.data { region::ScopeData::Node => - write!(f, "'{}s", scope.item_local_id().as_usize()), + print!(cx, write("'{}s", scope.item_local_id().as_usize())), region::ScopeData::CallSite => - write!(f, "'{}cs", scope.item_local_id().as_usize()), + print!(cx, write("'{}cs", scope.item_local_id().as_usize())), region::ScopeData::Arguments => - write!(f, "'{}as", scope.item_local_id().as_usize()), + print!(cx, write("'{}as", scope.item_local_id().as_usize())), region::ScopeData::Destruction => - write!(f, "'{}ds", scope.item_local_id().as_usize()), - region::ScopeData::Remainder(first_statement_index) => write!( - f, + print!(cx, write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => print!(cx, write( "'{}_{}rs", scope.item_local_id().as_usize(), first_statement_index.index() - ), + )), } } ty::ReVar(region_vid) if cx.identify_regions => { - write!(f, "{:?}", region_vid) + print!(cx, print_debug(region_vid)) } ty::ReVar(region_vid) => { - write!(f, "{}", region_vid) + print!(cx, print_display(region_vid)) } ty::ReScope(_) | ty::ReErased => Ok(()), - ty::ReStatic => write!(f, "'static"), - ty::ReEmpty => write!(f, "'"), + ty::ReStatic => print!(cx, write("'static")), + ty::ReEmpty => print!(cx, write("'")), // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => write!(f, "{:?}", vid), + ty::ReClosureBound(vid) => print!(cx, write("{:?}", vid)), } } debug { match *self { ty::ReEarlyBound(ref data) => { - write!(f, "ReEarlyBound({}, {})", + print!(cx, write("ReEarlyBound({}, {})", data.index, - data.name) + data.name)) } ty::ReClosureBound(ref vid) => { - write!(f, "ReClosureBound({:?})", - vid) + print!(cx, write("ReClosureBound({:?})", + vid)) } ty::ReLateBound(binder_id, ref bound_region) => { - write!(f, "ReLateBound({:?}, {:?})", + print!(cx, write("ReLateBound({:?}, {:?})", binder_id, - bound_region) + bound_region)) } - ty::ReFree(ref fr) => write!(f, "{:?}", fr), + ty::ReFree(ref fr) => print!(cx, write("{:?}", fr)), ty::ReScope(id) => { - write!(f, "ReScope({:?})", id) + print!(cx, write("ReScope({:?})", id)) } - ty::ReStatic => write!(f, "ReStatic"), + ty::ReStatic => print!(cx, write("ReStatic")), ty::ReVar(ref vid) => { - write!(f, "{:?}", vid) + print!(cx, write("{:?}", vid)) } ty::RePlaceholder(placeholder) => { - write!(f, "RePlaceholder({:?})", placeholder) + print!(cx, write("RePlaceholder({:?})", placeholder)) } - ty::ReEmpty => write!(f, "ReEmpty"), + ty::ReEmpty => print!(cx, write("ReEmpty")), - ty::ReErased => write!(f, "ReErased") + ty::ReErased => print!(cx, write("ReErased")) } } } @@ -897,7 +889,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::RegionKind { - fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { if cx.is_verbose { return true; } @@ -934,17 +926,17 @@ impl ty::RegionKind { } define_print! { - () ty::FreeRegion, (self, f, cx) { + () ty::FreeRegion, (self, cx) { debug { - write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + print!(cx, write("ReFree({:?}, {:?})", self.scope, self.bound_region)) } } } define_print! { - () ty::Variance, (self, f, cx) { + () ty::Variance, (self, cx) { debug { - f.write_str(match *self { + cx.printer.fmt.write_str(match *self { ty::Covariant => "+", ty::Contravariant => "-", ty::Invariant => "o", @@ -955,21 +947,22 @@ define_print! { } define_print! { - ('tcx) ty::FnSig<'tcx>, (self, f, cx) { + ('tcx) ty::FnSig<'tcx>, (self, cx) { display { if self.unsafety == hir::Unsafety::Unsafe { - write!(f, "unsafe ")?; + print!(cx, write("unsafe "))?; } if self.abi != Abi::Rust { - write!(f, "extern {} ", self.abi)?; + print!(cx, write("extern {} ", self.abi))?; } - write!(f, "fn")?; - cx.fn_sig(f, self.inputs(), self.c_variadic, self.output()) + print!(cx, write("fn"))?; + cx.fn_sig(self.inputs(), self.c_variadic, self.output()) } debug { - write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) + print!(cx, write("({:?}; c_variadic: {})->{:?}", + self.inputs(), self.c_variadic, self.output())) } } } @@ -999,15 +992,15 @@ impl fmt::Debug for ty::FloatVid { } define_print! { - () ty::RegionVid, (self, f, cx) { + () ty::RegionVid, (self, cx) { display { if cx.is_verbose { - return self.print_debug(f, cx); + return self.print_debug(cx); } let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return write!(f, "'{:?}", counter); + return print!(cx, write("'{:?}", counter)); } Ok(()) @@ -1017,10 +1010,10 @@ define_print! { // to keep NLL borrowck working even with `-Zverbose`. let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return write!(f, "'{:?}", counter); + return print!(cx, write("'{:?}", counter)); } - write!(f, "'_#{}r", self.index()) + print!(cx, write("'_#{}r", self.index())) } } } @@ -1029,7 +1022,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::RegionVid { - fn display_outputs_anything(&self, cx: &mut PrintCx<'_, '_, '_>) -> bool { + fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { + // HACK(eddyb) `pub(crate)` only for `ty::print`. + pub(crate) fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { if cx.is_verbose { return true; } @@ -1097,16 +998,17 @@ define_print_multi! { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, cx) { display { - cx.parameterized(self.def_id, self.substs, Namespace::TypeNS, iter::empty()) + let _ = cx.print_def_path( + self.def_id, + Some(self.substs), + Namespace::TypeNS, + iter::empty(), + )?; + Ok(()) } debug { - print!(cx, - write("<"), - print(self.self_ty()), - write(" as "), - print_display(self), - write(">") - ) + let _ = cx.path_qualified(self.self_ty(), Some(*self))?; + Ok(()) } } } @@ -1152,7 +1054,12 @@ define_print! { FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); print!(cx, print(sig), write(" {{"))?; - cx.parameterized(def_id, substs, Namespace::ValueNS, iter::empty())?; + let _ = cx.print_def_path( + def_id, + Some(substs), + Namespace::ValueNS, + iter::empty(), + )?; print!(cx, write("}}")) } FnPtr(ref bare_fn) => { @@ -1175,7 +1082,13 @@ define_print! { } } Adt(def, substs) => { - cx.parameterized(def.did, substs, Namespace::TypeNS, iter::empty()) + let _ = cx.print_def_path( + def.did, + Some(substs), + Namespace::TypeNS, + iter::empty(), + )?; + Ok(()) } Dynamic(data, r) => { let print_r = r.display_outputs_anything(cx); @@ -1190,12 +1103,13 @@ define_print! { Ok(()) } Foreign(def_id) => { - cx.parameterized( + let _ = cx.print_def_path( def_id, - subst::InternalSubsts::empty(), + None, Namespace::TypeNS, iter::empty(), - ) + )?; + Ok(()) } Projection(ref data) => data.print(cx), UnnormalizedProjection(ref data) => { @@ -1215,7 +1129,7 @@ define_print! { if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { print!(cx, write("{}", name))?; let mut substs = substs.iter(); - // FIXME(eddyb) print this with `parameterized`. + // FIXME(eddyb) print this with `print_def_path`. if let Some(first) = substs.next() { print!(cx, write("::<"))?; print!(cx, write("{}", first))?; @@ -1477,7 +1391,13 @@ define_print! { define_print! { ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { display { - cx.parameterized(self.item_def_id, self.substs, Namespace::TypeNS, iter::empty()) + let _ = cx.print_def_path( + self.item_def_id, + Some(self.substs), + Namespace::TypeNS, + iter::empty(), + )?; + Ok(()) } } } @@ -1505,16 +1425,33 @@ define_print! { ty::Predicate::Projection(ref predicate) => predicate.print(cx), ty::Predicate::WellFormed(ty) => print!(cx, print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { - print!(cx, write("the trait `{}` is object-safe", - cx.tcx.def_path_str(trait_def_id))) + print!(cx, write("the trait `"))?; + let _ = cx.print_def_path( + trait_def_id, + None, + Namespace::TypeNS, + iter::empty(), + )?; + print!(cx, write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - print!(cx, write("the closure `{}` implements the trait `{}`", - cx.tcx.def_path_str(closure_def_id), kind)) + print!(cx, write("the closure `"))?; + let _ = cx.print_def_path( + closure_def_id, + None, + Namespace::ValueNS, + iter::empty(), + )?; + print!(cx, write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { print!(cx, write("the constant `"))?; - cx.parameterized(def_id, substs, Namespace::ValueNS, iter::empty())?; + let _ = cx.print_def_path( + def_id, + Some(substs), + Namespace::ValueNS, + iter::empty(), + )?; print!(cx, write("` can be evaluated")) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index b417091704d72..4c7b00ae0780d 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -93,7 +93,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::print::{PrintCx, Printer}; +use rustc::ty::print::{PrettyPath, PrettyPrinter, PrintCx, Printer}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -106,8 +106,9 @@ use syntax_pos::symbol::Symbol; use log::debug; -use std::fmt::Write; -use std::mem::discriminant; +use std::fmt::{self, Write}; +use std::iter; +use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { @@ -225,9 +226,9 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { ty::print::with_forced_absolute_paths(|| { - PrintCx::new(tcx, SymbolPathPrinter) - .print_def_path(def_id, None, Namespace::ValueNS) - .into_interned() + let mut cx = PrintCx::new(tcx, SymbolPath::new(tcx)); + let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); + cx.printer.into_interned() }) } @@ -323,7 +324,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let mut buf = SymbolPath::from_interned(tcx.def_symbol_name(def_id), tcx); if instance.is_vtable_shim() { - buf.push("{{vtable-shim}}"); + let _ = buf.write_str("{{vtable-shim}}"); } buf.finish(hash) @@ -347,6 +348,12 @@ struct SymbolPath { result: String, temp_buf: String, strict_naming: bool, + + // When `true`, `finalize_pending_component` is a noop. + // This is needed when recursing into `path_qualified`, + // or `path_generic_args`, as any nested paths are + // logically within one component. + keep_within_component: bool, } impl SymbolPath { @@ -355,6 +362,7 @@ impl SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), strict_naming: tcx.has_strict_asm_symbol_naming(), + keep_within_component: false, }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result @@ -365,109 +373,139 @@ impl SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), strict_naming: tcx.has_strict_asm_symbol_naming(), + keep_within_component: false, }; result.result.push_str(&symbol.as_str()); result } - fn into_interned(self) -> ty::SymbolName { + fn into_interned(mut self) -> ty::SymbolName { + self.finalize_pending_component(); ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str(), } } - fn push(&mut self, text: &str) { - self.temp_buf.clear(); - let need_underscore = sanitize(&mut self.temp_buf, text, self.strict_naming); - let _ = write!( - self.result, - "{}", - self.temp_buf.len() + (need_underscore as usize) - ); - if need_underscore { - self.result.push('_'); + fn finalize_pending_component(&mut self) { + if !self.keep_within_component && !self.temp_buf.is_empty() { + let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf); + self.temp_buf.clear(); } - self.result.push_str(&self.temp_buf); } fn finish(mut self, hash: u64) -> String { + self.finalize_pending_component(); // E = end name-sequence let _ = write!(self.result, "17h{:016x}E", hash); self.result } } -struct SymbolPathPrinter; +// HACK(eddyb) this relies on using the `fmt` interface to get +// `PrettyPrinter` aka pretty printing of e.g. types in paths, +// symbol names should have their own printing machinery. -impl Printer for SymbolPathPrinter { - type Path = SymbolPath; +impl Printer for SymbolPath { + type Path = Result; fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - let mut path = SymbolPath::new(self.tcx); - path.push(&self.tcx.original_crate_name(cnum).as_str()); - path + self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?; + Ok(PrettyPath { empty: false }) + } + fn path_qualified( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Self::Path { + let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); + let r = self.pretty_path_qualified(self_ty, trait_ref); + self.printer.keep_within_component = kept_within_component; + r } fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - let mut path = SymbolPath::new(self.tcx); - path.push(text); - path + self.printer.write_str(text)?; + Ok(PrettyPath { empty: false }) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, + _: Self::Path, text: &str, ) -> Self::Path { - path.push(text); - path + self.printer.finalize_pending_component(); + self.printer.write_str(text)?; + Ok(PrettyPath { empty: false }) + } + fn path_generic_args( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + path: Self::Path, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + ns: Namespace, + projections: impl Iterator>, + ) -> Self::Path { + let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); + let r = self.pretty_path_generic_args(path, params, substs, ns, projections); + self.printer.keep_within_component = kept_within_component; + r } } -// Name sanitation. LLVM will happily accept identifiers with weird names, but -// gas doesn't! -// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ -// NVPTX assembly has more strict naming rules than gas, so additionally, dots -// are replaced with '$' there. -// -// returns true if an underscore must be added at the start -fn sanitize(result: &mut String, s: &str, strict_naming: bool) -> bool { - for c in s.chars() { - match c { - // Escape these with $ sequences - '@' => result.push_str("$SP$"), - '*' => result.push_str("$BP$"), - '&' => result.push_str("$RF$"), - '<' => result.push_str("$LT$"), - '>' => result.push_str("$GT$"), - '(' => result.push_str("$LP$"), - ')' => result.push_str("$RP$"), - ',' => result.push_str("$C$"), - - '-' | ':' | '.' if strict_naming => { - // NVPTX doesn't support these characters in symbol names. - result.push('$') +impl PrettyPrinter for SymbolPath {} + +impl fmt::Write for SymbolPath { + fn write_str(&mut self, s: &str) -> fmt::Result { + // Name sanitation. LLVM will happily accept identifiers with weird names, but + // gas doesn't! + // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ + // NVPTX assembly has more strict naming rules than gas, so additionally, dots + // are replaced with '$' there. + + for c in s.chars() { + if self.temp_buf.is_empty() { + match c { + 'a'..='z' | 'A'..='Z' | '_' => {} + _ => { + // Underscore-qualify anything that didn't start as an ident. + self.temp_buf.push('_'); + } + } } + match c { + // Escape these with $ sequences + '@' => self.temp_buf.push_str("$SP$"), + '*' => self.temp_buf.push_str("$BP$"), + '&' => self.temp_buf.push_str("$RF$"), + '<' => self.temp_buf.push_str("$LT$"), + '>' => self.temp_buf.push_str("$GT$"), + '(' => self.temp_buf.push_str("$LP$"), + ')' => self.temp_buf.push_str("$RP$"), + ',' => self.temp_buf.push_str("$C$"), + + '-' | ':' | '.' if self.strict_naming => { + // NVPTX doesn't support these characters in symbol names. + self.temp_buf.push('$') + } - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - '-' | ':' => result.push('.'), - - // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c), - - _ => { - result.push('$'); - for c in c.escape_unicode().skip(1) { - match c { - '{' => {} - '}' => result.push('$'), - c => result.push(c), + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + '-' | ':' => self.temp_buf.push('.'), + + // These are legal symbols + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.temp_buf.push(c), + + _ => { + self.temp_buf.push('$'); + for c in c.escape_unicode().skip(1) { + match c { + '{' => {} + '}' => self.temp_buf.push('$'), + c => self.temp_buf.push(c), + } } } } } - } - // Underscore-qualify anything that didn't start as an ident. - !result.is_empty() && result.as_bytes()[0] != '_' as u8 - && !(result.as_bytes()[0] as char).is_xid_start() + Ok(()) + } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6cf8a9896d513..f629447fc64fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,7 +39,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::default::Default; use std::{mem, slice, vec}; -use std::iter::{FromIterator, once}; +use std::iter::{self, FromIterator, once}; use std::rc::Rc; use std::str::FromStr; use std::cell::RefCell; @@ -4235,6 +4235,18 @@ where F: Fn(DefId) -> Def { fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { vec![self.tcx.original_crate_name(cnum).to_string()] } + fn path_qualified( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Self::Path { + // This shouldn't ever be needed, but just in case: + if let Some(trait_ref) = trait_ref { + vec![format!("{:?}", trait_ref)] + } else { + vec![format!("<{}>", self_ty)] + } + } fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { vec![text.to_string()] } @@ -4246,10 +4258,20 @@ where F: Fn(DefId) -> Def { path.push(text.to_string()); path } + fn path_generic_args( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + path: Self::Path, + _params: &[ty::GenericParamDef], + _substs: SubstsRef<'tcx>, + _ns: Namespace, + _projections: impl Iterator>, + ) -> Self::Path { + path + } } let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, Namespace::TypeNS); + .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()); hir::Path { span: DUMMY_SP, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 58ba827ee05f3..2ac44d0109f3a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,7 @@ #![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(in_band_lifetimes)] #![feature(nll)] #![feature(set_stdio)] #![feature(test)] diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 992527017fb7c..c712137e828f9 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -5,7 +5,7 @@ mod foo { pub struct Foo { x: u32 } impl Foo { - #[rustc_symbol_name] //~ ERROR _ZN15impl1..foo..Foo3bar + #[rustc_symbol_name] //~ ERROR _ZN5impl13foo3Foo3bar #[rustc_def_path] //~ ERROR def-path(foo::Foo::bar) fn bar() { } } diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr index d225c53e4927a..eda8646b5b4de 100644 --- a/src/test/ui/symbol-names/impl1.stderr +++ b/src/test/ui/symbol-names/impl1.stderr @@ -1,4 +1,4 @@ -error: symbol-name(_ZN15impl1..foo..Foo3bar17hc487d6ec13fe9124E) +error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E) --> $DIR/impl1.rs:8:9 | LL | #[rustc_symbol_name] From aec5a484812e2e6d0077a960997f1f51f18c1c8a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 21 Dec 2018 17:31:33 +0200 Subject: [PATCH 110/157] rustc: move <...>-less impl path special-case to pretty_path_qualified. --- src/librustc/ty/print.rs | 65 ++++++++++------------ src/librustc/util/ppaux.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 18 ++++-- src/librustdoc/clean/mod.rs | 4 +- 4 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 45762460f2dbc..77fed9cf1d15c 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -173,10 +173,9 @@ pub trait Printer: Sized { self: &mut PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, + ns: Namespace, ) -> Self::Path; #[must_use] - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; - #[must_use] fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, path: Self::Path, @@ -291,7 +290,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { let trait_ref = ty::TraitRef::new(parent_def_id, substs); - self.path_qualified(trait_ref.self_ty(), Some(trait_ref)) + self.path_qualified(trait_ref.self_ty(), Some(trait_ref), ns) } else { self.print_def_path(parent_def_id, substs, ns, iter::empty()) } @@ -367,35 +366,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // Otherwise, try to give a good form that would be valid language // syntax. Preferably using associated item notation. - - if let Some(trait_ref) = impl_trait_ref { - // Trait impls. - return self.path_qualified(self_ty, Some(trait_ref)); - } - - // Inherent impls. Try to print `Foo::bar` for an inherent - // impl on `Foo`, but fallback to `::bar` if self-type is - // anything other than a simple path. - match self_ty.sty { - ty::Adt(adt_def, substs) => { - self.print_def_path(adt_def.did, Some(substs), ns, iter::empty()) - } - - ty::Foreign(did) => self.print_def_path(did, None, ns, iter::empty()), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::Str => { - self.path_impl(&self_ty.to_string()) - } - - _ => { - self.path_qualified(self_ty, None) - } - } + self.path_qualified(self_ty, impl_trait_ref, ns) } } @@ -587,7 +558,30 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { &mut self, self_ty: Ty<'tcx>, trait_ref: Option>, + ns: Namespace, ) -> P::Path { + if trait_ref.is_none() { + // Inherent impls. Try to print `Foo::bar` for an inherent + // impl on `Foo`, but fallback to `::bar` if self-type is + // anything other than a simple path. + match self_ty.sty { + ty::Adt(adt_def, substs) => { + return self.print_def_path(adt_def.did, Some(substs), ns, iter::empty()); + } + ty::Foreign(did) => { + return self.print_def_path(did, None, ns, iter::empty()); + } + + ty::Bool | ty::Char | ty::Str | + ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + self_ty.print_display(self)?; + return Ok(PrettyPath { empty: false }); + } + + _ => {} + } + } + write!(self.printer, "<")?; self_ty.print_display(self)?; if let Some(trait_ref) = trait_ref { @@ -781,12 +775,9 @@ impl Printer for FmtPrinter { self: &mut PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, + ns: Namespace, ) -> Self::Path { - self.pretty_path_qualified(self_ty, trait_ref) - } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - write!(self.printer, "{}", text)?; - Ok(PrettyPath { empty: false }) + self.pretty_path_qualified(self_ty, trait_ref, ns) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2c38c437cf6e7..3c34d2540990a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1007,7 +1007,7 @@ define_print! { Ok(()) } debug { - let _ = cx.path_qualified(self.self_ty(), Some(*self))?; + let _ = cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS)?; Ok(()) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 4c7b00ae0780d..0ea141b6574b9 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -416,16 +416,24 @@ impl Printer for SymbolPath { self: &mut PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, + ns: Namespace, ) -> Self::Path { + // HACK(eddyb) avoid `keep_within_component` for the cases + // that print without `<...>` around `self_ty`. + match self_ty.sty { + ty::Adt(..) | ty::Foreign(_) | + ty::Bool | ty::Char | ty::Str | + ty::Int(_) | ty::Uint(_) | ty::Float(_) if trait_ref.is_none() => { + return self.pretty_path_qualified(self_ty, trait_ref, ns); + } + _ => {} + } + let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); - let r = self.pretty_path_qualified(self_ty, trait_ref); + let r = self.pretty_path_qualified(self_ty, trait_ref, ns); self.printer.keep_within_component = kept_within_component; r } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - self.printer.write_str(text)?; - Ok(PrettyPath { empty: false }) - } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, _: Self::Path, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f629447fc64fa..4cc18125e0499 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4239,6 +4239,7 @@ where F: Fn(DefId) -> Def { self: &mut PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, + _ns: Namespace, ) -> Self::Path { // This shouldn't ever be needed, but just in case: if let Some(trait_ref) = trait_ref { @@ -4247,9 +4248,6 @@ where F: Fn(DefId) -> Def { vec![format!("<{}>", self_ty)] } } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - vec![text.to_string()] - } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, mut path: Self::Path, From 39fd54a418b08051623505ff5263fe8714f40b4c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 21 Dec 2018 20:08:01 +0200 Subject: [PATCH 111/157] rustc: move the `FORCE_IMPL_FILENAME_LINE` hack into `print_def_path`. --- src/librustc/ty/print.rs | 83 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 77fed9cf1d15c..e0a5a2fcf843b 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -162,8 +162,10 @@ pub trait Printer: Sized { impl_def_id: DefId, substs: Option>, ns: Namespace, + self_ty: Ty<'tcx>, + trait_ref: Option>, ) -> Self::Path { - self.default_print_impl_path(impl_def_id, substs, ns) + self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref) } #[must_use] @@ -273,7 +275,16 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } DefPathData::Impl => { - self.print_impl_path(def_id, substs, ns) + let mut self_ty = self.tcx.type_of(def_id); + if let Some(substs) = substs { + self_ty = self_ty.subst(self.tcx, substs); + } + + let mut impl_trait_ref = self.tcx.impl_trait_ref(def_id); + if let Some(substs) = substs { + impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); + } + self.print_impl_path(def_id, substs, ns, self_ty, impl_trait_ref) } _ => { @@ -323,30 +334,24 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { fn default_print_impl_path( &mut self, impl_def_id: DefId, - substs: Option>, + _substs: Option>, ns: Namespace, + self_ty: Ty<'tcx>, + impl_trait_ref: Option>, ) -> P::Path { - debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); + debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", + impl_def_id, self_ty, impl_trait_ref); // Decide whether to print the parent path for the impl. // Logically, since impls are global, it's never needed, but // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let mut self_ty = self.tcx.type_of(impl_def_id); - if let Some(substs) = substs { - self_ty = self_ty.subst(self.tcx, substs); - } + let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), }; - - let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); - if let Some(substs) = substs { - impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); - } let in_trait_mod = match impl_trait_ref { None => false, Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), @@ -702,7 +707,7 @@ impl Printer for FmtPrinter { ns: Namespace, projections: impl Iterator>, ) -> Self::Path { - // FIXME(eddyb) avoid querying `tcx.generics_of` + // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); if // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` @@ -720,35 +725,31 @@ impl Printer for FmtPrinter { } } - self.default_print_def_path(def_id, substs, ns, projections) - } - fn print_impl_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> Self::Path { - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - FORCE_ABSOLUTE.with(|force| force.get()) || - !impl_def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; + let key = self.tcx.def_key(def_id); + if let DefPathData::Impl = key.disambiguated_data.data { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = + // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` + FORCE_ABSOLUTE.with(|force| force.get()) || + !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; - if !use_types { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); - let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); - let span = self.tcx.def_span(impl_def_id); - return self.path_append(path, &format!("", span)); + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); + let span = self.tcx.def_span(def_id); + return self.path_append(path, &format!("", span)); + } } - self.default_print_impl_path(impl_def_id, substs, ns) + self.default_print_def_path(def_id, substs, ns, projections) } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { From df6650f38cb2bed40fb1b1fe5d6a6e08dab963e2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 28 Dec 2018 06:09:22 +0200 Subject: [PATCH 112/157] rustc: move `...::` printing into `pretty_path_qualified`. --- src/librustc/ty/print.rs | 39 +++++++++++++------- src/librustc/util/ppaux.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 41 ++++++++++++++++++---- src/librustdoc/clean/mod.rs | 9 +++-- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index e0a5a2fcf843b..77768975e25a1 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -173,6 +173,7 @@ pub trait Printer: Sized { #[must_use] fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, @@ -301,7 +302,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { let trait_ref = ty::TraitRef::new(parent_def_id, substs); - self.path_qualified(trait_ref.self_ty(), Some(trait_ref), ns) + self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns) } else { self.print_def_path(parent_def_id, substs, ns, iter::empty()) } @@ -357,21 +358,18 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), }; - if !in_self_mod && !in_trait_mod { + let prefix_path = if !in_self_mod && !in_trait_mod { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); - if let Some(trait_ref) = impl_trait_ref { - return self.path_append(path, &format!("", trait_ref, self_ty)); - } else { - return self.path_append(path, &format!("", self_ty)); - } - } + Some(self.print_def_path(parent_def_id, None, ns, iter::empty())) + } else { + // Otherwise, try to give a good form that would be valid language + // syntax. Preferably using associated item notation. + None + }; - // Otherwise, try to give a good form that would be valid language - // syntax. Preferably using associated item notation. - self.path_qualified(self_ty, impl_trait_ref, ns) + self.path_qualified(prefix_path, self_ty, impl_trait_ref, ns) } } @@ -561,10 +559,24 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { pub fn pretty_path_qualified( &mut self, + impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> P::Path { + if let Some(prefix) = impl_prefix { + // HACK(eddyb) going through `path_append` means symbol name + // computation gets to handle its equivalent of `::` correctly. + let _ = self.path_append(prefix, "")?; + return Ok(PrettyPath { empty: false }); + } + if trait_ref.is_none() { // Inherent impls. Try to print `Foo::bar` for an inherent // impl on `Foo`, but fallback to `::bar` if self-type is @@ -774,11 +786,12 @@ impl Printer for FmtPrinter { } fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> Self::Path { - self.pretty_path_qualified(self_ty, trait_ref, ns) + self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 3c34d2540990a..6384a2af8ef00 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1007,7 +1007,7 @@ define_print! { Ok(()) } debug { - let _ = cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS)?; + let _ = cx.path_qualified(None, self.self_ty(), Some(*self), Namespace::TypeNS)?; Ok(()) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 0ea141b6574b9..c4de355aa442c 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -387,7 +387,7 @@ impl SymbolPath { } fn finalize_pending_component(&mut self) { - if !self.keep_within_component && !self.temp_buf.is_empty() { + if !self.temp_buf.is_empty() { let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf); self.temp_buf.clear(); } @@ -414,6 +414,7 @@ impl Printer for SymbolPath { } fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, @@ -423,25 +424,51 @@ impl Printer for SymbolPath { match self_ty.sty { ty::Adt(..) | ty::Foreign(_) | ty::Bool | ty::Char | ty::Str | - ty::Int(_) | ty::Uint(_) | ty::Float(_) if trait_ref.is_none() => { - return self.pretty_path_qualified(self_ty, trait_ref, ns); + ty::Int(_) | ty::Uint(_) | ty::Float(_) + if impl_prefix.is_none() && trait_ref.is_none() => + { + return self.pretty_path_qualified(None, self_ty, trait_ref, ns); } _ => {} } + // HACK(eddyb) make sure to finalize the last component of the + // `impl` prefix, to avoid it fusing with the following text. + let impl_prefix = impl_prefix.map(|prefix| { + let mut prefix = self.path_append(prefix, "")?; + + // HACK(eddyb) also avoid an unnecessary `::`. + prefix.empty = true; + + Ok(prefix) + }); + let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); - let r = self.pretty_path_qualified(self_ty, trait_ref, ns); + let r = self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns); self.printer.keep_within_component = kept_within_component; r } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, - _: Self::Path, + path: Self::Path, text: &str, ) -> Self::Path { - self.printer.finalize_pending_component(); + let mut path = path?; + + if self.keep_within_component { + // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. + if !path.empty { + self.printer.write_str("::")?; + } else { + path.empty = text.is_empty(); + } + } else { + self.printer.finalize_pending_component(); + path.empty = false; + } + self.printer.write_str(text)?; - Ok(PrettyPath { empty: false }) + Ok(path) } fn path_generic_args( self: &mut PrintCx<'_, '_, 'tcx, Self>, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4cc18125e0499..bfc7c7859f5ed 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4237,16 +4237,21 @@ where F: Fn(DefId) -> Def { } fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, _ns: Namespace, ) -> Self::Path { + let mut path = impl_prefix.unwrap_or(vec![]); + // This shouldn't ever be needed, but just in case: if let Some(trait_ref) = trait_ref { - vec![format!("{:?}", trait_ref)] + path.push(format!("{:?}", trait_ref)); } else { - vec![format!("<{}>", self_ty)] + path.push(format!("<{}>", self_ty)); } + + path } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, From 66cc029dd78ba5df23998a1966c7f9222e5c9c1c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 28 Dec 2018 07:00:30 +0200 Subject: [PATCH 113/157] rustc: assert `ty::print::FORCE_ABSOLUTE` isn't needed anymore. --- src/librustc/infer/error_reporting/mod.rs | 67 ++++++++++++++++++++--- src/librustc/ty/print.rs | 14 ++--- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c99ab215b3580..04f0710436b5d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::error::TypeError; use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable}; use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use std::{cmp, fmt}; +use std::{cmp, fmt, iter}; use syntax_pos::{Pos, Span}; mod note; @@ -444,20 +444,69 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { terr: &TypeError<'tcx>, sp: Span, ) { + use hir::def::Namespace; + use hir::def_id::CrateNum; + use ty::print::{PrintCx, Printer}; + use ty::subst::Substs; + + struct AbsolutePathPrinter; + + struct NonTrivialPath; + + impl Printer for AbsolutePathPrinter { + type Path = Result, NonTrivialPath>; + + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) + } + fn path_qualified<'tcx>( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + _impl_prefix: Option, + _self_ty: Ty<'tcx>, + _trait_ref: Option>, + _ns: Namespace, + ) -> Self::Path { + Err(NonTrivialPath) + } + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + path: Self::Path, + text: &str, + ) -> Self::Path { + let mut path = path?; + path.push(text.to_string()); + Ok(path) + } + fn path_generic_args<'tcx>( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + path: Self::Path, + _params: &[ty::GenericParamDef], + _substs: &'tcx Substs<'tcx>, + _ns: Namespace, + _projections: impl Iterator>, + ) -> Self::Path { + path + } + } + let report_path_match = |err: &mut DiagnosticBuilder<'_>, did1: DefId, did2: DefId| { // Only external crates, if either is from a local // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { - let exp_path = self.tcx.def_path_str(did1); - let found_path = self.tcx.def_path_str(did2); - // HACK(eddyb) switch form `with_forced_absolute_paths` - // to a custom implementation of `ty::print::Printer`. - let (exp_abs_path, found_abs_path) = ty::print::with_forced_absolute_paths(|| { - (self.tcx.def_path_str(did1), self.tcx.def_path_str(did2)) - }); + let abs_path = |def_id| { + PrintCx::new(self.tcx, AbsolutePathPrinter) + .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + }; + // We compare strings because DefPath can be different // for imported and non-imported crates - if exp_path == found_path || exp_abs_path == found_abs_path { + let same_path = || -> Result<_, NonTrivialPath> { + Ok( + self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) || + abs_path(did1)? == abs_path(did2)? + ) + }; + if same_path().unwrap_or(false) { let crate_name = self.tcx.crate_name(did1.krate); err.span_note( sp, diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 77768975e25a1..dca9ddc4a5b40 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -722,9 +722,9 @@ impl Printer for FmtPrinter { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); - if // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - !FORCE_ABSOLUTE.with(|force| force.get()) && - generics.as_ref().and_then(|g| g.parent).is_none() { + // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` + assert!(!FORCE_ABSOLUTE.with(|force| force.get())); + if generics.as_ref().and_then(|g| g.parent).is_none() { if let Some(path) = self.try_print_visible_def_path(def_id) { let path = if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; @@ -742,8 +742,6 @@ impl Printer for FmtPrinter { // Always use types for non-local impls, where types are always // available, and filename/line-number is mostly uninteresting. let use_types = - // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - FORCE_ABSOLUTE.with(|force| force.get()) || !def_id.is_local() || { // Otherwise, use filename/line-number if forced. let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); @@ -766,10 +764,8 @@ impl Printer for FmtPrinter { fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - if FORCE_ABSOLUTE.with(|force| force.get()) { - write!(self.printer, "{}", self.tcx.original_crate_name(cnum))?; - return Ok(PrettyPath { empty: false }); - } + assert!(!FORCE_ABSOLUTE.with(|force| force.get())); + if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. From 36f64f15fc0c530493206342d5e4c80f7643fc1d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 28 Dec 2018 07:27:44 +0200 Subject: [PATCH 114/157] rustc: remove `ty::print::FORCE_ABSOLUTE` altogether. --- src/librustc/infer/error_reporting/mod.rs | 4 +-- src/librustc/ty/print.rs | 39 +--------------------- src/librustc_codegen_utils/symbol_names.rs | 8 ++--- 3 files changed, 6 insertions(+), 45 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 04f0710436b5d..c27281911aa0e 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -447,7 +447,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { use hir::def::Namespace; use hir::def_id::CrateNum; use ty::print::{PrintCx, Printer}; - use ty::subst::Substs; + use ty::subst::SubstsRef; struct AbsolutePathPrinter; @@ -481,7 +481,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self: &mut PrintCx<'_, '_, 'tcx, Self>, path: Self::Path, _params: &[ty::GenericParamDef], - _substs: &'tcx Substs<'tcx>, + _substs: SubstsRef<'tcx>, _ns: Namespace, _projections: impl Iterator>, ) -> Self::Path { diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index dca9ddc4a5b40..0fda55423aad2 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -16,25 +16,10 @@ use std::iter; use std::ops::Deref; thread_local! { - static FORCE_ABSOLUTE: Cell = Cell::new(false); static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); } -/// Enforces that def_path_str always returns an absolute path and -/// also enables "type-based" impl paths. This is used when building -/// symbols that contain types, where we want the crate name to be -/// part of the symbol. -pub fn with_forced_absolute_paths R, R>(f: F) -> R { - FORCE_ABSOLUTE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - /// Force us to name impls with just the filename/line number. We /// normally try to use types. But at some points, notably while printing /// cycle errors, this can result in extra or suboptimal error output, @@ -223,24 +208,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. It is relative to the current crate - /// root, unless with_forced_absolute_paths was used. - pub fn def_path_str_with_substs_and_ns( - self, - def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> String { - debug!("def_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); - let mut s = String::new(); - let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) - .print_def_path(def_id, substs, ns, iter::empty()); - s - } - - /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. It is relative to the current crate - /// root, unless with_forced_absolute_paths was used. + /// suitable for user output. pub fn def_path_str(self, def_id: DefId) -> String { let ns = self.guess_def_namespace(def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); @@ -722,8 +690,6 @@ impl Printer for FmtPrinter { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); - // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - assert!(!FORCE_ABSOLUTE.with(|force| force.get())); if generics.as_ref().and_then(|g| g.parent).is_none() { if let Some(path) = self.try_print_visible_def_path(def_id) { let path = if let (Some(generics), Some(substs)) = (generics, substs) { @@ -763,9 +729,6 @@ impl Printer for FmtPrinter { } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` - assert!(!FORCE_ABSOLUTE.with(|force| force.get())); - if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index c4de355aa442c..8f31e91fa79fc 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -225,11 +225,9 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - ty::print::with_forced_absolute_paths(|| { - let mut cx = PrintCx::new(tcx, SymbolPath::new(tcx)); - let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); - cx.printer.into_interned() - }) + let mut cx = PrintCx::new(tcx, SymbolPath::new(tcx)); + let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); + cx.printer.into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { From 27ddf2cec8126fbf1a272cee6ce6cb1c18b97e2a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 28 Dec 2018 10:08:30 +0200 Subject: [PATCH 115/157] rustc: replace node_path_str with uses of def_path_str. --- src/librustc/hir/map/mod.rs | 3 ++- src/librustc/ty/print.rs | 7 ------- src/librustc_driver/pretty.rs | 2 +- src/librustc_save_analysis/dump_visitor.rs | 21 ++++++++++++++------- src/librustc_save_analysis/lib.rs | 22 +++++++++++++++------- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 747e65ff4b55f..600e7e21e9998 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1351,7 +1351,8 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { // the user-friendly path, otherwise fall back to stringifying DefPath. crate::ty::tls::with_opt(|tcx| { if let Some(tcx) = tcx { - tcx.node_path_str(id) + let def_id = map.local_def_id(id); + tcx.def_path_str(def_id) } else if let Some(path) = map.def_path_from_id(id) { path.data.into_iter().map(|elem| { elem.data.to_string() diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 0fda55423aad2..e9cd09aa539b1 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -4,7 +4,6 @@ use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use syntax::ast; use syntax::symbol::{keywords, Symbol}; use rustc_data_structures::fx::FxHashSet; @@ -217,12 +216,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .print_def_path(def_id, None, ns, iter::empty()); s } - - /// Returns a string identifying this local node-id. - // FIXME(eddyb) remove in favor of calling `def_path_str` directly. - pub fn node_path_str(self, id: ast::NodeId) -> String { - self.def_path_str(self.hir().local_def_id(id)) - } } impl PrintCx<'a, 'gcx, 'tcx, P> { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 3182b2ce30c6d..dde88a212408d 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -471,7 +471,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { } fn node_path(&self, id: ast::NodeId) -> Option { - Some(self.tcx.node_path_str(id)) + Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id))) } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 8e68a13e1e1a4..3fea515ae401e 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -429,7 +429,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { vis: ast::Visibility, attrs: &'l [Attribute], ) { - let qualname = format!("::{}", self.tcx.node_path_str(id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(id))); if !self.span.filter_generated(ident.span) { let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt); @@ -470,7 +471,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { debug!("process_struct {:?} {:?}", item, item.span); let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let kind = match item.node { ast::ItemKind::Struct(_, _) => DefKind::Struct, @@ -682,7 +684,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { methods: &'l [ast::TraitItem], ) { let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let mut val = name.clone(); if !generics.params.is_empty() { val.push_str(&generic_params_to_string(&generics.params)); @@ -1093,7 +1096,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ast::TraitItemKind::Type(ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(trait_item.id))); if !self.span.filter_generated(trait_item.ident.span) { let span = self.span_from_span(trait_item.ident.span); @@ -1300,7 +1304,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc // only get called for the root module of a crate. assert_eq!(id, ast::CRATE_NODE_ID); - let qualname = format!("::{}", self.tcx.node_path_str(id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(id))); let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(span); @@ -1389,7 +1394,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.nest_scope(item.id, |v| visit::walk_mod(v, m)); } Ty(ref ty, ref ty_params) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let value = ty_to_string(&ty); if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); @@ -1418,7 +1424,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.process_generic_params(ty_params, &qualname, item.id); } Existential(ref _bounds, ref ty_params) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); // FIXME do something with _bounds let value = String::new(); if !self.span.filter_generated(item.ident.span) { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 97b9db34ed525..7ad5b7ce8c73e 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -134,7 +134,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { filter!(self.span_utils, item.ident.span); @@ -184,7 +185,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_item_data(&self, item: &ast::Item) -> Option { match item.node { ast::ItemKind::Fn(ref decl, .., ref generics, _) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Function, @@ -202,7 +204,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Static(ref typ, ..) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); @@ -225,7 +228,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Const(ref typ, _) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); @@ -247,7 +251,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Mod(ref m) => { - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(m.inner); @@ -274,7 +279,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ItemKind::Enum(ref def, _) => { let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.node_path_str(item.id)); + let qualname = format!("::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id))); filter!(self.span_utils, item.ident.span); let variants_str = def.variants .iter() @@ -358,7 +364,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option { if let Some(ident) = field.ident { let name = ident.to_string(); - let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); + let qualname = format!("::{}::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(scope)), + ident); filter!(self.span_utils, ident.span); let def_id = self.tcx.hir().local_def_id(field.id); let typ = self.tcx.type_of(def_id).to_string(); From 387ea61ec146722daa9fcf5f2658ea5ee2211f0c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 9 Jan 2019 12:13:39 +0200 Subject: [PATCH 116/157] rustc: make ppaux' print macro use only one closure. --- src/librustc/util/ppaux.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6384a2af8ef00..a381f8f4e8a64 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -252,8 +252,11 @@ macro_rules! print_inner { }; } macro_rules! print { - ( $cx:expr $(, $kind:ident $data:tt)+ ) => { - Ok(())$(.and_then(|_| print_inner!($cx, $kind $data)))+ + ( $cx:expr, $($kind:ident $data:tt),+ ) => { + (|| -> fmt::Result { + $(print_inner!($cx, $kind $data)?;)+ + Ok(()) + })() }; } From 972af5e808eb76b449e7af6ee087bb611c722326 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 9 Jan 2019 13:05:05 +0200 Subject: [PATCH 117/157] rustc: rename ppaux' print macro to just p and make its cx input implicit. --- src/librustc/util/ppaux.rs | 366 +++++++++++++++++++------------------ 1 file changed, 193 insertions(+), 173 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a381f8f4e8a64..fa0acd1a301f7 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -195,6 +195,7 @@ macro_rules! gen_print_impl { impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { type Output = fmt::Result; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { + define_scoped_cx!($cx); if $cx.is_debug $dbg else $disp } @@ -204,6 +205,7 @@ macro_rules! gen_print_impl { impl Print<'tcx, P> for $target { type Output = fmt::Result; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { + define_scoped_cx!($cx); if $cx.is_debug $dbg else $disp } @@ -244,21 +246,29 @@ macro_rules! define_print_multi { }; } macro_rules! print_inner { - ( $cx:expr, write ($($data:expr),+) ) => { - write!($cx.printer, $($data),+) + (write ($($data:expr),+)) => { + write!(scoped_cx!().printer, $($data),+) }; - ( $cx:expr, $kind:ident ($data:expr) ) => { - $data.$kind($cx) + ($kind:ident ($data:expr)) => { + $data.$kind(scoped_cx!()) }; } -macro_rules! print { - ( $cx:expr, $($kind:ident $data:tt),+ ) => { +macro_rules! p { + ($($kind:ident $data:tt),+) => { (|| -> fmt::Result { - $(print_inner!($cx, $kind $data)?;)+ + $(print_inner!($kind $data)?;)+ Ok(()) })() }; } +macro_rules! define_scoped_cx { + ($cx:ident) => { + #[allow(unused_macros)] + macro_rules! scoped_cx { + () => ($cx) + } + }; +} impl PrintCx<'a, 'gcx, 'tcx, P> { fn fn_sig( @@ -267,20 +277,22 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { c_variadic: bool, output: Ty<'tcx>, ) -> fmt::Result { - print!(self, write("("))?; + define_scoped_cx!(self); + + p!(write("("))?; let mut inputs = inputs.iter(); if let Some(&ty) = inputs.next() { - print!(self, print_display(ty))?; + p!(print_display(ty))?; for &ty in inputs { - print!(self, write(", "), print_display(ty))?; + p!(write(", "), print_display(ty))?; } if c_variadic { - print!(self, write(", ..."))?; + p!(write(", ..."))?; } } - print!(self, write(")"))?; + p!(write(")"))?; if !output.is_unit() { - print!(self, write(" -> "), print_display(output))?; + p!(write(" -> "), print_display(output))?; } Ok(()) @@ -308,21 +320,28 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { + define_scoped_cx!(cx); + if empty { empty = false; - print!(cx, write("{}", start)) + p!(write("{}", start)) } else { - print!(cx, write("{}", cont)) + p!(write("{}", cont)) } }; + // NOTE(eddyb) this must be below `start_or_continue`'s definition + // as that also has a `define_scoped_cx` and that kind of shadowing + // is disallowed (name resolution thinks `scoped_cx!` is ambiguous). + define_scoped_cx!(self); + let old_region_index = self.region_index; let mut region_index = old_region_index; let new_value = self.tcx.replace_late_bound_regions(value, |br| { let _ = start_or_continue(self, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { - let _ = print!(self, write("{}", name)); + let _ = p!(write("{}", name)); br } ty::BrAnon(_) | @@ -335,7 +354,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { break name; } }; - let _ = print!(self, write("{}", name)); + let _ = p!(write("{}", name)); ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name) } }; @@ -431,7 +450,7 @@ define_print! { for (_, def_id) in auto_traits { if !first { - print!(cx, write(" + "))?; + p!(write(" + "))?; } first = false; @@ -502,7 +521,8 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { - print!(cx, write("UpvarId({:?};`{}`;{:?})", + define_scoped_cx!(cx); + p!(write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, cx.tcx.hir().name_by_hir_id(self.var_path.hir_id), self.closure_expr_id)) @@ -520,15 +540,15 @@ impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { define_print! { ('tcx) &'tcx ty::List>, (self, cx) { display { - print!(cx, write("{{"))?; + p!(write("{{"))?; let mut tys = self.iter(); if let Some(&ty) = tys.next() { - print!(cx, print(ty))?; + p!(print(ty))?; for &ty in tys { - print!(cx, write(", "), print(ty))?; + p!(write(", "), print(ty))?; } } - print!(cx, write("}}")) + p!(write("}}")) } } } @@ -536,7 +556,7 @@ define_print! { define_print! { ('tcx) ty::TypeAndMut<'tcx>, (self, cx) { display { - print!(cx, + p!( write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), print(self.ty)) } @@ -562,7 +582,7 @@ define_print! { define_print! { ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) { debug { - print!(cx, write("{:?} -> ", self.kind), print(self.target)) + p!(write("{:?} -> ", self.kind), print(self.target)) } } } @@ -576,14 +596,14 @@ define_print! { if let BrNamed(_, name) = *self { if name != "" && name != "'_" { - return print!(cx, write("{}", name)); + return p!(write("{}", name)); } } let highlight = RegionHighlightMode::get(); if let Some((region, counter)) = highlight.highlight_bound_region { if *self == region { - return print!(cx, write("'{}", counter)); + return p!(write("'{}", counter)); } } @@ -591,13 +611,13 @@ define_print! { } debug { return match *self { - BrAnon(n) => print!(cx, write("BrAnon({:?})", n)), - BrFresh(n) => print!(cx, write("BrFresh({:?})", n)), + BrAnon(n) => p!(write("BrAnon({:?})", n)), + BrFresh(n) => p!(write("BrFresh({:?})", n)), BrNamed(did, name) => { - print!(cx, write("BrNamed({:?}:{:?}, {})", + p!(write("BrNamed({:?}:{:?}, {})", did.krate, did.index, name)) } - BrEnv => print!(cx, write("BrEnv")), + BrEnv => p!(write("BrEnv")), }; } } @@ -638,10 +658,10 @@ define_print! { let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.placeholder_highlight(*self) { - return print!(cx, write("'{}", counter)); + return p!(write("'{}", counter)); } - print!(cx, print_display(self.name)) + p!(print_display(self.name)) } } } @@ -673,7 +693,7 @@ define_print! { // Watch out for region highlights. if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { - return print!(cx, write("'{:?}", n)); + return p!(write("'{:?}", n)); } // These printouts are concise. They do not contain all the information @@ -683,29 +703,29 @@ define_print! { match *self { ty::ReEarlyBound(ref data) => { if data.name != "'_" { - print!(cx, write("{}", data.name)) + p!(write("{}", data.name)) } else { Ok(()) } } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { - print!(cx, print_display(br)) + p!(print_display(br)) } ty::RePlaceholder(p) => { - print!(cx, print_display(p)) + p!(print_display(p)) } ty::ReScope(scope) if cx.identify_regions => { match scope.data { region::ScopeData::Node => - print!(cx, write("'{}s", scope.item_local_id().as_usize())), + p!(write("'{}s", scope.item_local_id().as_usize())), region::ScopeData::CallSite => - print!(cx, write("'{}cs", scope.item_local_id().as_usize())), + p!(write("'{}cs", scope.item_local_id().as_usize())), region::ScopeData::Arguments => - print!(cx, write("'{}as", scope.item_local_id().as_usize())), + p!(write("'{}as", scope.item_local_id().as_usize())), region::ScopeData::Destruction => - print!(cx, write("'{}ds", scope.item_local_id().as_usize())), - region::ScopeData::Remainder(first_statement_index) => print!(cx, write( + p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => p!(write( "'{}_{}rs", scope.item_local_id().as_usize(), first_statement_index.index() @@ -713,58 +733,58 @@ define_print! { } } ty::ReVar(region_vid) if cx.identify_regions => { - print!(cx, print_debug(region_vid)) + p!(print_debug(region_vid)) } ty::ReVar(region_vid) => { - print!(cx, print_display(region_vid)) + p!(print_display(region_vid)) } ty::ReScope(_) | ty::ReErased => Ok(()), - ty::ReStatic => print!(cx, write("'static")), - ty::ReEmpty => print!(cx, write("'")), + ty::ReStatic => p!(write("'static")), + ty::ReEmpty => p!(write("'")), // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => print!(cx, write("{:?}", vid)), + ty::ReClosureBound(vid) => p!(write("{:?}", vid)), } } debug { match *self { ty::ReEarlyBound(ref data) => { - print!(cx, write("ReEarlyBound({}, {})", + p!(write("ReEarlyBound({}, {})", data.index, data.name)) } ty::ReClosureBound(ref vid) => { - print!(cx, write("ReClosureBound({:?})", + p!(write("ReClosureBound({:?})", vid)) } ty::ReLateBound(binder_id, ref bound_region) => { - print!(cx, write("ReLateBound({:?}, {:?})", + p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region)) } - ty::ReFree(ref fr) => print!(cx, write("{:?}", fr)), + ty::ReFree(ref fr) => p!(write("{:?}", fr)), ty::ReScope(id) => { - print!(cx, write("ReScope({:?})", id)) + p!(write("ReScope({:?})", id)) } - ty::ReStatic => print!(cx, write("ReStatic")), + ty::ReStatic => p!(write("ReStatic")), ty::ReVar(ref vid) => { - print!(cx, write("{:?}", vid)) + p!(write("{:?}", vid)) } ty::RePlaceholder(placeholder) => { - print!(cx, write("RePlaceholder({:?})", placeholder)) + p!(write("RePlaceholder({:?})", placeholder)) } - ty::ReEmpty => print!(cx, write("ReEmpty")), + ty::ReEmpty => p!(write("ReEmpty")), - ty::ReErased => print!(cx, write("ReErased")) + ty::ReErased => p!(write("ReErased")) } } } @@ -817,7 +837,7 @@ impl ty::RegionKind { define_print! { () ty::FreeRegion, (self, cx) { debug { - print!(cx, write("ReFree({:?}, {:?})", self.scope, self.bound_region)) + p!(write("ReFree({:?}, {:?})", self.scope, self.bound_region)) } } } @@ -839,18 +859,18 @@ define_print! { ('tcx) ty::FnSig<'tcx>, (self, cx) { display { if self.unsafety == hir::Unsafety::Unsafe { - print!(cx, write("unsafe "))?; + p!(write("unsafe "))?; } if self.abi != Abi::Rust { - print!(cx, write("extern {} ", self.abi))?; + p!(write("extern {} ", self.abi))?; } - print!(cx, write("fn"))?; + p!(write("fn"))?; cx.fn_sig(self.inputs(), self.c_variadic, self.output()) } debug { - print!(cx, write("({:?}; c_variadic: {})->{:?}", + p!(write("({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())) } } @@ -889,7 +909,7 @@ define_print! { let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return print!(cx, write("'{:?}", counter)); + return p!(write("'{:?}", counter)); } Ok(()) @@ -899,10 +919,10 @@ define_print! { // to keep NLL borrowck working even with `-Zverbose`. let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return print!(cx, write("'{:?}", counter)); + return p!(write("'{:?}", counter)); } - print!(cx, write("'_#{}r", self.index())) + p!(write("'_#{}r", self.index())) } } } @@ -932,22 +952,22 @@ define_print! { return self.print_debug(cx); } match *self { - ty::TyVar(_) => print!(cx, write("_")), - ty::IntVar(_) => print!(cx, write("{}", "{integer}")), - ty::FloatVar(_) => print!(cx, write("{}", "{float}")), - ty::FreshTy(v) => print!(cx, write("FreshTy({})", v)), - ty::FreshIntTy(v) => print!(cx, write("FreshIntTy({})", v)), - ty::FreshFloatTy(v) => print!(cx, write("FreshFloatTy({})", v)) + ty::TyVar(_) => p!(write("_")), + ty::IntVar(_) => p!(write("{}", "{integer}")), + ty::FloatVar(_) => p!(write("{}", "{float}")), + ty::FreshTy(v) => p!(write("FreshTy({})", v)), + ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)), + ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) } } debug { match *self { - ty::TyVar(ref v) => print!(cx, write("{:?}", v)), - ty::IntVar(ref v) => print!(cx, write("{:?}", v)), - ty::FloatVar(ref v) => print!(cx, write("{:?}", v)), - ty::FreshTy(v) => print!(cx, write("FreshTy({:?})", v)), - ty::FreshIntTy(v) => print!(cx, write("FreshIntTy({:?})", v)), - ty::FreshFloatTy(v) => print!(cx, write("FreshFloatTy({:?})", v)) + ty::TyVar(ref v) => p!(write("{:?}", v)), + ty::IntVar(ref v) => p!(write("{:?}", v)), + ty::FloatVar(ref v) => p!(write("{:?}", v)), + ty::FreshTy(v) => p!(write("FreshTy({:?})", v)), + ty::FreshIntTy(v) => p!(write("FreshIntTy({:?})", v)), + ty::FreshFloatTy(v) => p!(write("FreshFloatTy({:?})", v)) } } } @@ -1020,68 +1040,68 @@ define_print! { ('tcx) ty::Ty<'tcx>, (self, cx) { display { match self.sty { - Bool => print!(cx, write("bool")), - Char => print!(cx, write("char")), - Int(t) => print!(cx, write("{}", t.ty_to_string())), - Uint(t) => print!(cx, write("{}", t.ty_to_string())), - Float(t) => print!(cx, write("{}", t.ty_to_string())), + Bool => p!(write("bool")), + Char => p!(write("char")), + Int(t) => p!(write("{}", t.ty_to_string())), + Uint(t) => p!(write("{}", t.ty_to_string())), + Float(t) => p!(write("{}", t.ty_to_string())), RawPtr(ref tm) => { - print!(cx, write("*{} ", match tm.mutbl { + p!(write("*{} ", match tm.mutbl { hir::MutMutable => "mut", hir::MutImmutable => "const", }))?; tm.ty.print(cx) } Ref(r, ty, mutbl) => { - print!(cx, write("&"))?; + p!(write("&"))?; if r.display_outputs_anything(cx) { - print!(cx, print_display(r), write(" "))?; + p!(print_display(r), write(" "))?; } ty::TypeAndMut { ty, mutbl }.print(cx) } - Never => print!(cx, write("!")), + Never => p!(write("!")), Tuple(ref tys) => { - print!(cx, write("("))?; + p!(write("("))?; let mut tys = tys.iter(); if let Some(&ty) = tys.next() { - print!(cx, print(ty), write(","))?; + p!(print(ty), write(","))?; if let Some(&ty) = tys.next() { - print!(cx, write(" "), print(ty))?; + p!(write(" "), print(ty))?; for &ty in tys { - print!(cx, write(", "), print(ty))?; + p!(write(", "), print(ty))?; } } } - print!(cx, write(")")) + p!(write(")")) } FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); - print!(cx, print(sig), write(" {{"))?; + p!(print(sig), write(" {{"))?; let _ = cx.print_def_path( def_id, Some(substs), Namespace::ValueNS, iter::empty(), )?; - print!(cx, write("}}")) + p!(write("}}")) } FnPtr(ref bare_fn) => { bare_fn.print(cx) } - Infer(infer_ty) => print!(cx, write("{}", infer_ty)), - Error => print!(cx, write("[type error]")), - Param(ref param_ty) => print!(cx, write("{}", param_ty)), + Infer(infer_ty) => p!(write("{}", infer_ty)), + Error => p!(write("[type error]")), + Param(ref param_ty) => p!(write("{}", param_ty)), Bound(debruijn, bound_ty) => { match bound_ty.kind { ty::BoundTyKind::Anon => { if debruijn == ty::INNERMOST { - print!(cx, write("^{}", bound_ty.var.index())) + p!(write("^{}", bound_ty.var.index())) } else { - print!(cx, write("^{}_{}", debruijn.index(), bound_ty.var.index())) + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) } } - ty::BoundTyKind::Param(p) => print!(cx, write("{}", p)), + ty::BoundTyKind::Param(p) => p!(write("{}", p)), } } Adt(def, substs) => { @@ -1096,12 +1116,12 @@ define_print! { Dynamic(data, r) => { let print_r = r.display_outputs_anything(cx); if print_r { - print!(cx, write("("))?; + p!(write("("))?; } - print!(cx, write("dyn "))?; + p!(write("dyn "))?; data.print(cx)?; if print_r { - print!(cx, write(" + "), print_display(r), write(")"))?; + p!(write(" + "), print_display(r), write(")"))?; } Ok(()) } @@ -1116,30 +1136,30 @@ define_print! { } Projection(ref data) => data.print(cx), UnnormalizedProjection(ref data) => { - print!(cx, write("Unnormalized("))?; + p!(write("Unnormalized("))?; data.print(cx)?; - print!(cx, write(")")) + p!(write(")")) } Placeholder(placeholder) => { - print!(cx, write("Placeholder({:?})", placeholder)) + p!(write("Placeholder({:?})", placeholder)) } Opaque(def_id, substs) => { if cx.is_verbose { - return print!(cx, write("Opaque({:?}, {:?})", def_id, substs)); + return p!(write("Opaque({:?}, {:?})", def_id, substs)); } let def_key = cx.tcx.def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - print!(cx, write("{}", name))?; + p!(write("{}", name))?; let mut substs = substs.iter(); // FIXME(eddyb) print this with `print_def_path`. if let Some(first) = substs.next() { - print!(cx, write("::<"))?; - print!(cx, write("{}", first))?; + p!(write("::<"))?; + p!(write("{}", first))?; for subst in substs { - print!(cx, write(", {}", subst))?; + p!(write(", {}", subst))?; } - print!(cx, write(">"))?; + p!(write(">"))?; } return Ok(()); } @@ -1149,7 +1169,7 @@ define_print! { let mut first = true; let mut is_sized = false; - print!(cx, write("impl"))?; + p!(write("impl"))?; for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. @@ -1158,36 +1178,36 @@ define_print! { continue; } - print!(cx, + p!( write("{}", if first { " " } else { "+" }), print(trait_ref))?; first = false; } } if !is_sized { - print!(cx, write("{}?Sized", if first { " " } else { "+" }))?; + p!(write("{}?Sized", if first { " " } else { "+" }))?; } else if first { - print!(cx, write(" Sized"))?; + p!(write(" Sized"))?; } Ok(()) } - Str => print!(cx, write("str")), + Str => p!(write("str")), Generator(did, substs, movability) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); let witness = substs.witness(did, cx.tcx); if movability == hir::GeneratorMovability::Movable { - print!(cx, write("[generator"))?; + p!(write("[generator"))?; } else { - print!(cx, write("[static generator"))?; + p!(write("[static generator"))?; } // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { - print!(cx, write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; + p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(cx, + p!( write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), @@ -1199,36 +1219,36 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - print!(cx, write("@{:?}", did))?; + p!(write("@{:?}", did))?; let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - print!(cx, + p!( write("{}{}:", sep, index), print(upvar_ty))?; sep = ", "; } } - print!(cx, write(" "), print(witness), write("]")) + p!(write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { cx.in_binder(&types) } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); - print!(cx, write("[closure"))?; + p!(write("[closure"))?; // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { if cx.tcx.sess.opts.debugging_opts.span_free_formats { - print!(cx, write("@{:?}", hir_id))?; + p!(write("@{:?}", hir_id))?; } else { - print!(cx, write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; + p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; } let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(cx, + p!( write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), @@ -1240,10 +1260,10 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - print!(cx, write("@{:?}", did))?; + p!(write("@{:?}", did))?; let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - print!(cx, + p!( write("{}{}:", sep, index), print(upvar_ty))?; sep = ", "; @@ -1251,34 +1271,34 @@ define_print! { } if cx.is_verbose { - print!(cx, write( + p!(write( " closure_kind_ty={:?} closure_sig_ty={:?}", substs.closure_kind_ty(did, cx.tcx), substs.closure_sig_ty(did, cx.tcx) ))?; } - print!(cx, write("]")) + p!(write("]")) }, Array(ty, sz) => { - print!(cx, write("["), print(ty), write("; "))?; + p!(write("["), print(ty), write("; "))?; match sz { ty::LazyConst::Unevaluated(_def_id, _substs) => { - print!(cx, write("_"))?; + p!(write("_"))?; } ty::LazyConst::Evaluated(c) => { match c.val { - ConstValue::Infer(..) => print!(cx, write("_"))?, + ConstValue::Infer(..) => p!(write("_"))?, ConstValue::Param(ParamConst { name, .. }) => - print!(cx, write("{}", name))?, - _ => print!(cx, write("{}", c.unwrap_usize(cx.tcx)))?, + p!(write("{}", name))?, + _ => p!(write("{}", c.unwrap_usize(cx.tcx)))?, } } } - print!(cx, write("]")) + p!(write("]")) } Slice(ty) => { - print!(cx, write("["), print(ty), write("]")) + p!(write("["), print(ty), write("]")) } } } @@ -1292,9 +1312,9 @@ define_print! { ('tcx) ConstValue<'tcx>, (self, cx) { display { match self { - ConstValue::Infer(..) => print!(cx, write("_")), - ConstValue::Param(ParamConst { name, .. }) => print!(cx, write("{}", name)), - _ => print!(cx, write("{:?}", self)), + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), + _ => p!(write("{:?}", self)), } } } @@ -1303,7 +1323,7 @@ define_print! { define_print! { ('tcx) ty::Const<'tcx>, (self, cx) { display { - print!(cx, write("{} : {}", self.val, self.ty)) + p!(write("{} : {}", self.val, self.ty)) } } } @@ -1313,8 +1333,8 @@ define_print! { display { match self { // FIXME(const_generics) this should print at least the type. - ty::LazyConst::Unevaluated(..) => print!(cx, write("_ : _")), - ty::LazyConst::Evaluated(c) => print!(cx, write("{}", c)), + ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), + ty::LazyConst::Evaluated(c) => p!(write("{}", c)), } } } @@ -1323,10 +1343,10 @@ define_print! { define_print! { () ty::ParamTy, (self, cx) { display { - print!(cx, write("{}", self.name)) + p!(write("{}", self.name)) } debug { - print!(cx, write("{}/#{}", self.name, self.idx)) + p!(write("{}/#{}", self.name, self.idx)) } } } @@ -1334,10 +1354,10 @@ define_print! { define_print! { () ty::ParamConst, (self, cx) { display { - print!(cx, write("{}", self.name)) + p!(write("{}", self.name)) } debug { - print!(cx, write("{}/#{}", self.name, self.index)) + p!(write("{}/#{}", self.name, self.index)) } } } @@ -1350,7 +1370,7 @@ define_print_multi! { ] (self, cx) { display { - print!(cx, print(self.0), write(" : "), print(self.1)) + p!(print(self.0), write(" : "), print(self.1)) } } } @@ -1358,7 +1378,7 @@ define_print_multi! { define_print! { ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) { display { - print!(cx, print(self.a), write(" <: "), print(self.b)) + p!(print(self.a), write(" <: "), print(self.b)) } } } @@ -1366,11 +1386,11 @@ define_print! { define_print! { ('tcx) ty::TraitPredicate<'tcx>, (self, cx) { debug { - print!(cx, write("TraitPredicate({:?})", + p!(write("TraitPredicate({:?})", self.trait_ref)) } display { - print!(cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) } } } @@ -1378,7 +1398,7 @@ define_print! { define_print! { ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) { debug { - print!(cx, + p!( write("ProjectionPredicate("), print(self.projection_ty), write(", "), @@ -1386,7 +1406,7 @@ define_print! { write(")")) } display { - print!(cx, print(self.projection_ty), write(" == "), print(self.ty)) + p!(print(self.projection_ty), write(" == "), print(self.ty)) } } } @@ -1409,9 +1429,9 @@ define_print! { () ty::ClosureKind, (self, cx) { display { match *self { - ty::ClosureKind::Fn => print!(cx, write("Fn")), - ty::ClosureKind::FnMut => print!(cx, write("FnMut")), - ty::ClosureKind::FnOnce => print!(cx, write("FnOnce")), + ty::ClosureKind::Fn => p!(write("Fn")), + ty::ClosureKind::FnMut => p!(write("FnMut")), + ty::ClosureKind::FnOnce => p!(write("FnOnce")), } } } @@ -1426,36 +1446,36 @@ define_print! { ty::Predicate::RegionOutlives(ref predicate) => predicate.print(cx), ty::Predicate::TypeOutlives(ref predicate) => predicate.print(cx), ty::Predicate::Projection(ref predicate) => predicate.print(cx), - ty::Predicate::WellFormed(ty) => print!(cx, print(ty), write(" well-formed")), + ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { - print!(cx, write("the trait `"))?; + p!(write("the trait `"))?; let _ = cx.print_def_path( trait_def_id, None, Namespace::TypeNS, iter::empty(), )?; - print!(cx, write("` is object-safe")) + p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - print!(cx, write("the closure `"))?; + p!(write("the closure `"))?; let _ = cx.print_def_path( closure_def_id, None, Namespace::ValueNS, iter::empty(), )?; - print!(cx, write("` implements the trait `{}`", kind)) + p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - print!(cx, write("the constant `"))?; + p!(write("the constant `"))?; let _ = cx.print_def_path( def_id, Some(substs), Namespace::ValueNS, iter::empty(), )?; - print!(cx, write("` can be evaluated")) + p!(write("` can be evaluated")) } } } @@ -1468,14 +1488,14 @@ define_print! { ty::Predicate::Projection(ref pair) => pair.print(cx), ty::Predicate::WellFormed(ty) => ty.print(cx), ty::Predicate::ObjectSafe(trait_def_id) => { - print!(cx, write("ObjectSafe({:?})", trait_def_id)) + p!(write("ObjectSafe({:?})", trait_def_id)) } ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - print!(cx, write("ClosureKind({:?}, {:?}, {:?})", + p!(write("ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - print!(cx, write("ConstEvaluatable({:?}, {:?})", def_id, substs)) + p!(write("ConstEvaluatable({:?}, {:?})", def_id, substs)) } } } @@ -1486,16 +1506,16 @@ define_print! { ('tcx) Kind<'tcx>, (self, cx) { display { match self.unpack() { - UnpackedKind::Lifetime(lt) => print!(cx, print(lt)), - UnpackedKind::Type(ty) => print!(cx, print(ty)), - UnpackedKind::Const(ct) => print!(cx, print(ct)), + UnpackedKind::Lifetime(lt) => p!(print(lt)), + UnpackedKind::Type(ty) => p!(print(ty)), + UnpackedKind::Const(ct) => p!(print(ct)), } } debug { match self.unpack() { - UnpackedKind::Lifetime(lt) => print!(cx, print(lt)), - UnpackedKind::Type(ty) => print!(cx, print(ty)), - UnpackedKind::Const(ct) => print!(cx, print(ct)), + UnpackedKind::Lifetime(lt) => p!(print(lt)), + UnpackedKind::Type(ty) => p!(print(ty)), + UnpackedKind::Const(ct) => p!(print(ct)), } } } From 5616ca857dd05e5e62b4bfcd11bd1ea0f2e22f5e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 9 Jan 2019 16:30:10 +0200 Subject: [PATCH 118/157] rustc: uniformize ty::print's error handling by requiring Result. --- src/librustc/infer/error_reporting/mod.rs | 20 ++-- src/librustc/ty/print.rs | 110 +++++++++++---------- src/librustc/util/ppaux.rs | 10 +- src/librustc_codegen_utils/symbol_names.rs | 34 ++++--- src/librustdoc/clean/mod.rs | 24 +++-- src/librustdoc/lib.rs | 1 + 6 files changed, 114 insertions(+), 85 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c27281911aa0e..b777b0dc9f37f 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -454,9 +454,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { struct NonTrivialPath; impl Printer for AbsolutePathPrinter { - type Path = Result, NonTrivialPath>; + type Error = NonTrivialPath; - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + type Path = Vec; + + fn path_crate( + self: &mut PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified<'tcx>( @@ -465,15 +470,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _self_ty: Ty<'tcx>, _trait_ref: Option>, _ns: Namespace, - ) -> Self::Path { + ) -> Result { Err(NonTrivialPath) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, - path: Self::Path, + mut path: Self::Path, text: &str, - ) -> Self::Path { - let mut path = path?; + ) -> Result { path.push(text.to_string()); Ok(path) } @@ -484,8 +488,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _substs: SubstsRef<'tcx>, _ns: Namespace, _projections: impl Iterator>, - ) -> Self::Path { - path + ) -> Result { + Ok(path) } } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index e9cd09aa539b1..f179619b5f83c 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -109,16 +109,20 @@ impl

PrintCx<'a, 'gcx, 'tcx, P> { pub trait Print<'tcx, P> { type Output; + type Error; - fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output; - fn print_display(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { + fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result; + fn print_display( + &self, + cx: &mut PrintCx<'_, '_, 'tcx, P>, + ) -> Result { let old_debug = cx.is_debug; cx.is_debug = false; let result = self.print(cx); cx.is_debug = old_debug; result } - fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { + fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result { let old_debug = cx.is_debug; cx.is_debug = true; let result = self.print(cx); @@ -128,19 +132,19 @@ pub trait Print<'tcx, P> { } pub trait Printer: Sized { + type Error; + type Path; - #[must_use] fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, ns: Namespace, projections: impl Iterator>, - ) -> Self::Path { + ) -> Result { self.default_print_def_path(def_id, substs, ns, projections) } - #[must_use] fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, @@ -148,27 +152,26 @@ pub trait Printer: Sized { ns: Namespace, self_ty: Ty<'tcx>, trait_ref: Option>, - ) -> Self::Path { + ) -> Result { self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref) } - #[must_use] - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; - #[must_use] + fn path_crate( + self: &mut PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result; fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_prefix: Option, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, - ) -> Self::Path; - #[must_use] + ) -> Result; fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, path: Self::Path, text: &str, - ) -> Self::Path; - #[must_use] + ) -> Result; fn path_generic_args( self: &mut PrintCx<'_, '_, 'tcx, Self>, path: Self::Path, @@ -176,7 +179,7 @@ pub trait Printer: Sized { substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, - ) -> Self::Path; + ) -> Result; } #[must_use] @@ -185,7 +188,7 @@ pub struct PrettyPath { } /// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: Printer> + fmt::Write {} +pub trait PrettyPrinter: Printer + fmt::Write {} impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always @@ -225,7 +228,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { substs: Option>, ns: Namespace, projections: impl Iterator>, - ) -> P::Path { + ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); let key = self.tcx.def_key(def_id); debug!("default_print_def_path: key={:?}", key); @@ -263,12 +266,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { let trait_ref = ty::TraitRef::new(parent_def_id, substs); - self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns) + self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns)? } else { - self.print_def_path(parent_def_id, substs, ns, iter::empty()) + self.print_def_path(parent_def_id, substs, ns, iter::empty())? } } else { - self.print_def_path(parent_def_id, None, ns, iter::empty()) + self.print_def_path(parent_def_id, None, ns, iter::empty())? }; let path = match key.disambiguated_data.data { // Skip `::{{constructor}}` on tuple/unit structs. @@ -278,7 +281,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { self.path_append( path, &key.disambiguated_data.data.as_interned_str().as_str(), - ) + )? } }; @@ -287,7 +290,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let params = &generics.params[has_own_self as usize..]; self.path_generic_args(path, params, substs, ns, projections) } else { - path + Ok(path) } } } @@ -300,7 +303,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { ns: Namespace, self_ty: Ty<'tcx>, impl_trait_ref: Option>, - ) -> P::Path { + ) -> Result { debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", impl_def_id, self_ty, impl_trait_ref); @@ -323,7 +326,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - Some(self.print_def_path(parent_def_id, None, ns, iter::empty())) + Some(self.print_def_path(parent_def_id, None, ns, iter::empty())?) } else { // Otherwise, try to give a good form that would be valid language // syntax. Preferably using associated item notation. @@ -390,7 +393,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path(&mut self, def_id: DefId) -> Option { + fn try_print_visible_def_path(&mut self, def_id: DefId) -> Result, P::Error> { debug!("try_print_visible_def_path: def_id={:?}", def_id); // If `def_id` is a direct or injected extern crate, return the @@ -399,7 +402,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let cnum = def_id.krate; if cnum == LOCAL_CRATE { - return Some(self.path_crate(cnum)); + return Ok(Some(self.path_crate(cnum)?)); } // In local mode, when we encounter a crate other than @@ -421,21 +424,21 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); let path = if !span.is_dummy() { - self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())? } else { - self.path_crate(cnum) + self.path_crate(cnum)? }; - return Some(path); + return Ok(Some(path)); } None => { - return Some(self.path_crate(cnum)); + return Ok(Some(self.path_crate(cnum)?)); } _ => {}, } } if def_id.is_local() { - return None; + return Ok(None); } let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); @@ -453,8 +456,14 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { cur_def_key = self.tcx.def_key(parent); } - let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = self.try_print_visible_def_path(visible_parent)?; + let visible_parent = match visible_parent_map.get(&def_id).cloned() { + Some(parent) => parent, + None => return Ok(None), + }; + let path = match self.try_print_visible_def_path(visible_parent)? { + Some(path) => path, + None => return Ok(None), + }; let actual_parent = self.tcx.parent(def_id); let data = cur_def_key.disambiguated_data.data; @@ -515,7 +524,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }, }; debug!("try_print_visible_def_path: symbol={:?}", symbol); - Some(self.path_append(path, &symbol)) + Ok(Some(self.path_append(path, &symbol)?)) } pub fn pretty_path_qualified( @@ -524,7 +533,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, - ) -> P::Path { + ) -> Result { if let Some(prefix) = impl_prefix { // HACK(eddyb) going through `path_append` means symbol name // computation gets to handle its equivalent of `::` correctly. @@ -582,9 +591,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, - ) -> P::Path { - let path = path?; - + ) -> Result { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { if empty { @@ -671,7 +678,9 @@ impl fmt::Write for FmtPrinter { } impl Printer for FmtPrinter { - type Path = Result; + type Error = fmt::Error; + + type Path = PrettyPath; fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -679,20 +688,20 @@ impl Printer for FmtPrinter { substs: Option>, ns: Namespace, projections: impl Iterator>, - ) -> Self::Path { + ) -> Result { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); if generics.as_ref().and_then(|g| g.parent).is_none() { - if let Some(path) = self.try_print_visible_def_path(def_id) { + if let Some(path) = self.try_print_visible_def_path(def_id)? { let path = if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(path, params, substs, ns, projections) + self.path_generic_args(path, params, substs, ns, projections)? } else { path }; - return path; + return Ok(path); } } @@ -712,7 +721,7 @@ impl Printer for FmtPrinter { // pretty printing some span information. This should // only occur very early in the compiler pipeline. let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); + let path = self.print_def_path(parent_def_id, None, ns, iter::empty())?; let span = self.tcx.def_span(def_id); return self.path_append(path, &format!("", span)); } @@ -721,7 +730,10 @@ impl Printer for FmtPrinter { self.default_print_def_path(def_id, substs, ns, projections) } - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + fn path_crate( + self: &mut PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result { if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. @@ -742,16 +754,14 @@ impl Printer for FmtPrinter { self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, - ) -> Self::Path { + ) -> Result { self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, path: Self::Path, text: &str, - ) -> Self::Path { - let path = path?; - + ) -> Result { // FIXME(eddyb) this shouldn't happen, but is currently // the case for `extern { ... }` "foreign modules". if text.is_empty() { @@ -771,7 +781,7 @@ impl Printer for FmtPrinter { substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, - ) -> Self::Path { + ) -> Result { self.pretty_path_generic_args(path, params, substs, ns, projections) } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fa0acd1a301f7..d0d51e7f38c14 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -193,7 +193,8 @@ macro_rules! gen_display_debug { macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { - type Output = fmt::Result; + type Output = (); + type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { define_scoped_cx!($cx); if $cx.is_debug $dbg @@ -203,7 +204,8 @@ macro_rules! gen_print_impl { }; ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { impl Print<'tcx, P> for $target { - type Output = fmt::Result; + type Output = (); + type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { define_scoped_cx!($cx); if $cx.is_debug $dbg @@ -298,8 +300,8 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { Ok(()) } - fn in_binder(&mut self, value: &ty::Binder) -> fmt::Result - where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx> + fn in_binder(&mut self, value: &ty::Binder) -> Result + where T: Print<'tcx, P, Error = fmt::Error> + TypeFoldable<'tcx> { fn name_by_region_index(index: usize) -> InternedString { match index { diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 8f31e91fa79fc..c73c5950c0da5 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -404,9 +404,14 @@ impl SymbolPath { // symbol names should have their own printing machinery. impl Printer for SymbolPath { - type Path = Result; + type Error = fmt::Error; - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + type Path = PrettyPath; + + fn path_crate( + self: &mut PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result { self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?; Ok(PrettyPath { empty: false }) } @@ -416,7 +421,7 @@ impl Printer for SymbolPath { self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, - ) -> Self::Path { + ) -> Result { // HACK(eddyb) avoid `keep_within_component` for the cases // that print without `<...>` around `self_ty`. match self_ty.sty { @@ -432,14 +437,17 @@ impl Printer for SymbolPath { // HACK(eddyb) make sure to finalize the last component of the // `impl` prefix, to avoid it fusing with the following text. - let impl_prefix = impl_prefix.map(|prefix| { - let mut prefix = self.path_append(prefix, "")?; + let impl_prefix = match impl_prefix { + Some(prefix) => { + let mut prefix = self.path_append(prefix, "")?; - // HACK(eddyb) also avoid an unnecessary `::`. - prefix.empty = true; + // HACK(eddyb) also avoid an unnecessary `::`. + prefix.empty = true; - Ok(prefix) - }); + Some(prefix) + } + None => None, + }; let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); let r = self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns); @@ -448,11 +456,9 @@ impl Printer for SymbolPath { } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, - path: Self::Path, + mut path: Self::Path, text: &str, - ) -> Self::Path { - let mut path = path?; - + ) -> Result { if self.keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. if !path.empty { @@ -475,7 +481,7 @@ impl Printer for SymbolPath { substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, - ) -> Self::Path { + ) -> Result { let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); let r = self.pretty_path_generic_args(path, params, substs, ns, projections); self.printer.keep_within_component = kept_within_component; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bfc7c7859f5ed..2a8db6455bf22 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4230,10 +4230,15 @@ where F: Fn(DefId) -> Def { struct AbsolutePathPrinter; impl Printer for AbsolutePathPrinter { + type Error = !; + type Path = Vec; - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - vec![self.tcx.original_crate_name(cnum).to_string()] + fn path_crate( + self: &mut PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result { + Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -4241,7 +4246,7 @@ where F: Fn(DefId) -> Def { self_ty: Ty<'tcx>, trait_ref: Option>, _ns: Namespace, - ) -> Self::Path { + ) -> Result { let mut path = impl_prefix.unwrap_or(vec![]); // This shouldn't ever be needed, but just in case: @@ -4251,15 +4256,15 @@ where F: Fn(DefId) -> Def { path.push(format!("<{}>", self_ty)); } - path + Ok(path) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, mut path: Self::Path, text: &str, - ) -> Self::Path { + ) -> Result { path.push(text.to_string()); - path + Ok(path) } fn path_generic_args( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -4268,13 +4273,14 @@ where F: Fn(DefId) -> Def { _substs: SubstsRef<'tcx>, _ns: Namespace, _projections: impl Iterator>, - ) -> Self::Path { - path + ) -> Result { + Ok(path) } } let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()); + .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + .unwrap(); hir::Path { span: DUMMY_SP, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2ac44d0109f3a..fccf5a67ad465 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -18,6 +18,7 @@ #![feature(const_fn)] #![feature(drain_filter)] #![feature(inner_deref)] +#![feature(never_type)] #![recursion_limit="256"] From 37e918526a7107bc3c8de48f9a535b0100da40f5 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 10 Jan 2019 13:26:35 +0200 Subject: [PATCH 119/157] rustc: split off most of ty::print::PrintCx's fields into a separate struct. --- src/librustc/infer/error_reporting/mod.rs | 5 +- src/librustc/mir/mod.rs | 4 +- src/librustc/ty/print.rs | 69 ++++++++++++++-------- src/librustc/util/ppaux.rs | 61 +++++++++---------- src/librustc_codegen_utils/symbol_names.rs | 7 ++- src/librustdoc/clean/mod.rs | 6 +- 6 files changed, 86 insertions(+), 66 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index b777b0dc9f37f..68b2d201fb00a 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -498,8 +498,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { - PrintCx::new(self.tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + PrintCx::with(self.tcx, AbsolutePathPrinter, |mut cx| { + cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + }) }; // We compare strings because DefPath can be different diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ea3668cec1544..7ee8eec11ee42 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,8 +2369,8 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - ty::print::PrintCx::with(ty::print::FmtPrinter { fmt }, |cx| { - let region = if cx.is_verbose || cx.identify_regions { + ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter { fmt }, |cx| { + let region = if cx.config.is_verbose || cx.config.identify_regions { let mut region = region.to_string(); if region.len() > 0 { region.push(' '); diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index f179619b5f83c..d385d183e2b32 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -60,9 +60,7 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } } -pub struct PrintCx<'a, 'gcx, 'tcx, P> { - pub tcx: TyCtxt<'a, 'gcx, 'tcx>, - pub printer: P, +pub(crate) struct PrintConfig { pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, @@ -71,6 +69,25 @@ pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub(crate) binder_depth: usize, } +impl PrintConfig { + pub(crate) fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { + PrintConfig { + is_debug: false, + is_verbose: tcx.sess.verbose(), + identify_regions: tcx.sess.opts.debugging_opts.identify_regions, + used_region_names: None, + region_index: 0, + binder_depth: 0, + } + } +} + +pub struct PrintCx<'a, 'gcx, 'tcx, P> { + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, + pub printer: P, + pub(crate) config: &'a mut PrintConfig, +} + // HACK(eddyb) this is solely for `self: &mut PrintCx`, e.g. to // implement traits on the printer and call the methods on the context. impl

Deref for PrintCx<'_, '_, '_, P> { @@ -80,30 +97,29 @@ impl

Deref for PrintCx<'_, '_, '_, P> { } } -impl

PrintCx<'a, 'gcx, 'tcx, P> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, printer: P) -> Self { - PrintCx { +impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { + pub fn with( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + printer: P, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, P>) -> R, + ) -> R { + f(PrintCx { tcx, printer, - is_debug: false, - is_verbose: tcx.sess.verbose(), - identify_regions: tcx.sess.opts.debugging_opts.identify_regions, - used_region_names: None, - region_index: 0, - binder_depth: 0, - } + config: &mut PrintConfig::new(tcx), + }) } - pub(crate) fn with(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { - ty::tls::with(|tcx| f(PrintCx::new(tcx, printer))) + pub(crate) fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { + ty::tls::with(|tcx| PrintCx::with(tcx, printer, f)) } pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx> { let mut collector = LateBoundRegionNameCollector(Default::default()); value.visit_with(&mut collector); - self.used_region_names = Some(collector.0); - self.region_index = 0; + self.config.used_region_names = Some(collector.0); + self.config.region_index = 0; } } @@ -116,17 +132,17 @@ pub trait Print<'tcx, P> { &self, cx: &mut PrintCx<'_, '_, 'tcx, P>, ) -> Result { - let old_debug = cx.is_debug; - cx.is_debug = false; + let old_debug = cx.config.is_debug; + cx.config.is_debug = false; let result = self.print(cx); - cx.is_debug = old_debug; + cx.config.is_debug = old_debug; result } fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result { - let old_debug = cx.is_debug; - cx.is_debug = true; + let old_debug = cx.config.is_debug; + cx.config.is_debug = true; let result = self.print(cx); - cx.is_debug = old_debug; + cx.config.is_debug = old_debug; result } } @@ -215,8 +231,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let ns = self.guess_def_namespace(def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); - let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) - .print_def_path(def_id, None, ns, iter::empty()); + let _ = PrintCx::with(self, FmtPrinter { fmt: &mut s }, |mut cx| { + cx.print_def_path(def_id, None, ns, iter::empty()) + }); s } } @@ -613,7 +630,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }); // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = if self.is_verbose { + let num_supplied_defaults = if self.config.is_verbose { 0 } else { params.iter().rev().take_while(|param| { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d0d51e7f38c14..90300ecde2e5c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -161,7 +161,7 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { $with(&cx.tcx.lift(self).expect("could not lift for printing"), &mut cx) }) } @@ -197,7 +197,7 @@ macro_rules! gen_print_impl { type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { define_scoped_cx!($cx); - if $cx.is_debug $dbg + if $cx.config.is_debug $dbg else $disp } } @@ -208,7 +208,7 @@ macro_rules! gen_print_impl { type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { define_scoped_cx!($cx); - if $cx.is_debug $dbg + if $cx.config.is_debug $dbg else $disp } } @@ -316,7 +316,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // clearly differentiate between named and unnamed regions in // the output. We'll probably want to tweak this over time to // decide just how much information to give. - if self.binder_depth == 0 { + if self.config.binder_depth == 0 { self.prepare_late_bound_region_info(value); } @@ -337,7 +337,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // is disallowed (name resolution thinks `scoped_cx!` is ambiguous). define_scoped_cx!(self); - let old_region_index = self.region_index; + let old_region_index = self.config.region_index; let mut region_index = old_region_index; let new_value = self.tcx.replace_late_bound_regions(value, |br| { let _ = start_or_continue(self, "for<", ", "); @@ -365,16 +365,16 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { start_or_continue(self, "", "> ")?; // Push current state to gcx, and restore after writing new_value. - self.binder_depth += 1; - self.region_index = region_index; + self.config.binder_depth += 1; + self.config.region_index = region_index; let result = new_value.print_display(self); - self.region_index = old_region_index; - self.binder_depth -= 1; + self.config.region_index = old_region_index; + self.config.binder_depth -= 1; result } fn is_name_used(&self, name: &InternedString) -> bool { - match self.used_region_names { + match self.config.used_region_names { Some(ref names) => names.contains(name), None => false, } @@ -387,7 +387,7 @@ pub fn parameterized( substs: SubstsRef<'_>, ns: Namespace, ) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); let _ = cx.print_def_path(did, Some(substs), ns, iter::empty())?; Ok(()) @@ -404,8 +404,9 @@ define_print! { let mut resugared_principal = false; // Special-case `Fn(...) -> ...` and resugar it. - if !cx.is_verbose && cx.tcx.lang_items().fn_trait_kind(principal.def_id).is_some() { - if let Tuple(ref args) = principal.substs.type_at(0).sty { + let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); + if !cx.config.is_verbose && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { let _ = cx.print_def_path( @@ -486,7 +487,7 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { let _ = cx.print_def_path( self.def_id, None, @@ -500,7 +501,7 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { let _ = cx.print_def_path( self.did, None, @@ -522,7 +523,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { define_scoped_cx!(cx); p!(write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, @@ -592,7 +593,7 @@ define_print! { define_print! { () ty::BoundRegion, (self, cx) { display { - if cx.is_verbose { + if cx.config.is_verbose { return self.print_debug(cx); } @@ -630,7 +631,7 @@ define_print! { // NB: this must be kept in sync with the printing logic above. impl ty::BoundRegion { fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { - if cx.is_verbose { + if cx.config.is_verbose { return true; } @@ -654,7 +655,7 @@ impl ty::BoundRegion { define_print! { () ty::PlaceholderRegion, (self, cx) { display { - if cx.is_verbose { + if cx.config.is_verbose { return self.print_debug(cx); } @@ -673,7 +674,7 @@ define_print! { // NB: this must be kept in sync with the printing logic above. impl ty::PlaceholderRegion { fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { - if cx.is_verbose { + if cx.config.is_verbose { return true; } @@ -689,7 +690,7 @@ impl ty::PlaceholderRegion { define_print! { () ty::RegionKind, (self, cx) { display { - if cx.is_verbose { + if cx.config.is_verbose { return self.print_debug(cx); } @@ -717,7 +718,7 @@ define_print! { ty::RePlaceholder(p) => { p!(print_display(p)) } - ty::ReScope(scope) if cx.identify_regions => { + ty::ReScope(scope) if cx.config.identify_regions => { match scope.data { region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())), @@ -734,7 +735,7 @@ define_print! { )), } } - ty::ReVar(region_vid) if cx.identify_regions => { + ty::ReVar(region_vid) if cx.config.identify_regions => { p!(print_debug(region_vid)) } ty::ReVar(region_vid) => { @@ -801,7 +802,7 @@ define_print! { impl ty::RegionKind { // HACK(eddyb) `pub(crate)` only for `ty::print`. pub(crate) fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { - if cx.is_verbose { + if cx.config.is_verbose { return true; } @@ -822,7 +823,7 @@ impl ty::RegionKind { ty::RePlaceholder(p) => p.display_outputs_anything(cx), ty::ReScope(_) | - ty::ReVar(_) if cx.identify_regions => true, + ty::ReVar(_) if cx.config.identify_regions => true, ty::ReVar(region_vid) => region_vid.display_outputs_anything(cx), @@ -905,7 +906,7 @@ impl fmt::Debug for ty::FloatVid { define_print! { () ty::RegionVid, (self, cx) { display { - if cx.is_verbose { + if cx.config.is_verbose { return self.print_debug(cx); } @@ -934,7 +935,7 @@ define_print! { // NB: this must be kept in sync with the printing logic above. impl ty::RegionVid { fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { - if cx.is_verbose { + if cx.config.is_verbose { return true; } @@ -950,7 +951,7 @@ impl ty::RegionVid { define_print! { () ty::InferTy, (self, cx) { display { - if cx.is_verbose { + if cx.config.is_verbose { return self.print_debug(cx); } match *self { @@ -997,7 +998,7 @@ impl fmt::Debug for ty::FloatVarValue { for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|cx| cx.in_binder(cx.tcx.lift(self) + PrintCx::with_tls_tcx(|cx| cx.in_binder(cx.tcx.lift(self) .expect("could not lift for printing"))) } }*/ @@ -1146,7 +1147,7 @@ define_print! { p!(write("Placeholder({:?})", placeholder)) } Opaque(def_id, substs) => { - if cx.is_verbose { + if cx.config.is_verbose { return p!(write("Opaque({:?}, {:?})", def_id, substs)); } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index c73c5950c0da5..8f4b1d1638a80 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -225,9 +225,10 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - let mut cx = PrintCx::new(tcx, SymbolPath::new(tcx)); - let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); - cx.printer.into_interned() + PrintCx::with(tcx, SymbolPath::new(tcx), |mut cx| { + let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); + cx.printer.into_interned() + }) } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2a8db6455bf22..ffdf47db54723 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4278,9 +4278,9 @@ where F: Fn(DefId) -> Def { } } - let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) - .unwrap(); + let names = PrintCx::with(tcx, AbsolutePathPrinter, |mut cx| { + cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()).unwrap() + }); hir::Path { span: DUMMY_SP, From ab5d6fb302f0b74e825c6e3e829a9e5ce880b7d0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 10 Jan 2019 14:50:36 +0200 Subject: [PATCH 120/157] rustc: remove the closure from ppaux's p! macro (by making ? implicit). --- src/librustc/ty/print.rs | 8 +- src/librustc/util/ppaux.rs | 248 ++++++++++++++++++------------------- 2 files changed, 122 insertions(+), 134 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index d385d183e2b32..005dd18177d23 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -611,12 +611,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { ) -> Result { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - if empty { + write!(cx.printer, "{}", if empty { empty = false; - write!(cx.printer, "{}", start) + start } else { - write!(cx.printer, "{}", cont) - } + cont + }) }; let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 90300ecde2e5c..55e0544d2bbe5 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -196,9 +196,11 @@ macro_rules! gen_print_impl { type Output = (); type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { - define_scoped_cx!($cx); - if $cx.config.is_debug $dbg - else $disp + Ok({ + define_scoped_cx!($cx); + if $cx.config.is_debug $dbg + else $disp + }) } } }; @@ -207,9 +209,11 @@ macro_rules! gen_print_impl { type Output = (); type Error = fmt::Error; fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { - define_scoped_cx!($cx); - if $cx.config.is_debug $dbg - else $disp + Ok({ + define_scoped_cx!($cx); + if $cx.config.is_debug $dbg + else $disp + }) } } }; @@ -238,7 +242,7 @@ macro_rules! define_print { ( $generic:tt $target:ty, ($self:ident, $cx:ident) { display $disp:block } ) => { gen_print_impl! { $generic $target, ($self, $cx) yes $disp no { - write!($cx.printer, "{:?}", $self) + write!($cx.printer, "{:?}", $self)? } } }; } @@ -257,10 +261,9 @@ macro_rules! print_inner { } macro_rules! p { ($($kind:ident $data:tt),+) => { - (|| -> fmt::Result { - $(print_inner!($kind $data)?;)+ - Ok(()) - })() + { + $(print_inner!($kind $data)?);+ + } }; } macro_rules! define_scoped_cx { @@ -281,20 +284,20 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { ) -> fmt::Result { define_scoped_cx!(self); - p!(write("("))?; + p!(write("(")); let mut inputs = inputs.iter(); if let Some(&ty) = inputs.next() { - p!(print_display(ty))?; + p!(print_display(ty)); for &ty in inputs { - p!(write(", "), print_display(ty))?; + p!(write(", "), print_display(ty)); } if c_variadic { - p!(write(", ..."))?; + p!(write(", ...")); } } - p!(write(")"))?; + p!(write(")")); if !output.is_unit() { - p!(write(" -> "), print_display(output))?; + p!(write(" -> "), print_display(output)); } Ok(()) @@ -322,14 +325,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - define_scoped_cx!(cx); - - if empty { + write!(cx.printer, "{}", if empty { empty = false; - p!(write("{}", start)) + start } else { - p!(write("{}", cont)) - } + cont + }) }; // NOTE(eddyb) this must be below `start_or_continue`'s definition @@ -343,7 +344,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let _ = start_or_continue(self, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { - let _ = p!(write("{}", name)); + let _ = write!(self.printer, "{}", name); br } ty::BrAnon(_) | @@ -356,7 +357,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { break name; } }; - let _ = p!(write("{}", name)); + let _ = write!(self.printer, "{}", name); ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name) } }; @@ -453,7 +454,7 @@ define_print! { for (_, def_id) in auto_traits { if !first { - p!(write(" + "))?; + p!(write(" + ")); } first = false; @@ -464,8 +465,6 @@ define_print! { iter::empty(), )?; } - - Ok(()) } } } @@ -528,7 +527,8 @@ impl fmt::Debug for ty::UpvarId { p!(write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, cx.tcx.hir().name_by_hir_id(self.var_path.hir_id), - self.closure_expr_id)) + self.closure_expr_id)); + Ok(()) }) } } @@ -543,12 +543,12 @@ impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { define_print! { ('tcx) &'tcx ty::List>, (self, cx) { display { - p!(write("{{"))?; + p!(write("{{")); let mut tys = self.iter(); if let Some(&ty) = tys.next() { - p!(print(ty))?; + p!(print(ty)); for &ty in tys { - p!(write(", "), print(ty))?; + p!(write(", "), print(ty)); } } p!(write("}}")) @@ -571,13 +571,12 @@ define_print! { display { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - ty::Binder::bind(*self) + p!(print_display(ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) - .skip_binder() - .print_display(cx) + .skip_binder())) } debug { - self.print_display(cx) + p!(print_display(self)) } } } @@ -599,21 +598,20 @@ define_print! { if let BrNamed(_, name) = *self { if name != "" && name != "'_" { - return p!(write("{}", name)); + p!(write("{}", name)); + return Ok(()); } } let highlight = RegionHighlightMode::get(); if let Some((region, counter)) = highlight.highlight_bound_region { if *self == region { - return p!(write("'{}", counter)); + p!(write("'{}", counter)); } } - - Ok(()) } debug { - return match *self { + match *self { BrAnon(n) => p!(write("BrAnon({:?})", n)), BrFresh(n) => p!(write("BrFresh({:?})", n)), BrNamed(did, name) => { @@ -621,7 +619,7 @@ define_print! { did.krate, did.index, name)) } BrEnv => p!(write("BrEnv")), - }; + } } } } @@ -661,10 +659,10 @@ define_print! { let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.placeholder_highlight(*self) { - return p!(write("'{}", counter)); + p!(write("'{}", counter)); + } else { + p!(print_display(self.name)); } - - p!(print_display(self.name)) } } } @@ -696,7 +694,8 @@ define_print! { // Watch out for region highlights. if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { - return p!(write("'{:?}", n)); + p!(write("'{:?}", n)); + return Ok(()); } // These printouts are concise. They do not contain all the information @@ -707,8 +706,6 @@ define_print! { ty::ReEarlyBound(ref data) => { if data.name != "'_" { p!(write("{}", data.name)) - } else { - Ok(()) } } ty::ReLateBound(_, br) | @@ -742,7 +739,7 @@ define_print! { p!(print_display(region_vid)) } ty::ReScope(_) | - ty::ReErased => Ok(()), + ty::ReErased => {} ty::ReStatic => p!(write("'static")), ty::ReEmpty => p!(write("'")), @@ -853,7 +850,7 @@ define_print! { ty::Contravariant => "-", ty::Invariant => "o", ty::Bivariant => "*", - }) + })? } } } @@ -862,15 +859,15 @@ define_print! { ('tcx) ty::FnSig<'tcx>, (self, cx) { display { if self.unsafety == hir::Unsafety::Unsafe { - p!(write("unsafe "))?; + p!(write("unsafe ")); } if self.abi != Abi::Rust { - p!(write("extern {} ", self.abi))?; + p!(write("extern {} ", self.abi)); } - p!(write("fn"))?; - cx.fn_sig(self.inputs(), self.c_variadic, self.output()) + p!(write("fn")); + cx.fn_sig(self.inputs(), self.c_variadic, self.output())? } debug { p!(write("({:?}; c_variadic: {})->{:?}", @@ -912,20 +909,18 @@ define_print! { let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return p!(write("'{:?}", counter)); + p!(write("'{:?}", counter)); } - - Ok(()) } debug { // HACK(eddyb) this is duplicated from `display` printing, // to keep NLL borrowck working even with `-Zverbose`. let highlight = RegionHighlightMode::get(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - return p!(write("'{:?}", counter)); + p!(write("'{:?}", counter)); + } else { + p!(write("'_#{}r", self.index())); } - - p!(write("'_#{}r", self.index())) } } } @@ -1016,7 +1011,7 @@ define_print_multi! { ] (self, cx) { display { - cx.in_binder(self) + cx.in_binder(self)? } } } @@ -1030,11 +1025,9 @@ define_print! { Namespace::TypeNS, iter::empty(), )?; - Ok(()) } debug { let _ = cx.path_qualified(None, self.self_ty(), Some(*self), Namespace::TypeNS)?; - Ok(()) } } } @@ -1052,26 +1045,26 @@ define_print! { p!(write("*{} ", match tm.mutbl { hir::MutMutable => "mut", hir::MutImmutable => "const", - }))?; - tm.ty.print(cx) + })); + p!(print(tm.ty)) } Ref(r, ty, mutbl) => { - p!(write("&"))?; + p!(write("&")); if r.display_outputs_anything(cx) { - p!(print_display(r), write(" "))?; + p!(print_display(r), write(" ")); } - ty::TypeAndMut { ty, mutbl }.print(cx) + p!(print(ty::TypeAndMut { ty, mutbl })) } Never => p!(write("!")), Tuple(ref tys) => { - p!(write("("))?; + p!(write("(")); let mut tys = tys.iter(); if let Some(&ty) = tys.next() { - p!(print(ty), write(","))?; + p!(print(ty), write(",")); if let Some(&ty) = tys.next() { - p!(write(" "), print(ty))?; + p!(write(" "), print(ty)); for &ty in tys { - p!(write(", "), print(ty))?; + p!(write(", "), print(ty)); } } } @@ -1079,7 +1072,7 @@ define_print! { } FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); - p!(print(sig), write(" {{"))?; + p!(print(sig), write(" {{")); let _ = cx.print_def_path( def_id, Some(substs), @@ -1089,7 +1082,7 @@ define_print! { p!(write("}}")) } FnPtr(ref bare_fn) => { - bare_fn.print(cx) + p!(print(bare_fn)) } Infer(infer_ty) => p!(write("{}", infer_ty)), Error => p!(write("[type error]")), @@ -1114,19 +1107,16 @@ define_print! { Namespace::TypeNS, iter::empty(), )?; - Ok(()) } Dynamic(data, r) => { let print_r = r.display_outputs_anything(cx); if print_r { - p!(write("("))?; + p!(write("(")); } - p!(write("dyn "))?; - data.print(cx)?; + p!(write("dyn "), print(data)); if print_r { - p!(write(" + "), print_display(r), write(")"))?; + p!(write(" + "), print_display(r), write(")")); } - Ok(()) } Foreign(def_id) => { let _ = cx.print_def_path( @@ -1135,11 +1125,10 @@ define_print! { Namespace::TypeNS, iter::empty(), )?; - Ok(()) } - Projection(ref data) => data.print(cx), + Projection(ref data) => p!(print(data)), UnnormalizedProjection(ref data) => { - p!(write("Unnormalized("))?; + p!(write("Unnormalized(")); data.print(cx)?; p!(write(")")) } @@ -1148,21 +1137,22 @@ define_print! { } Opaque(def_id, substs) => { if cx.config.is_verbose { - return p!(write("Opaque({:?}, {:?})", def_id, substs)); + p!(write("Opaque({:?}, {:?})", def_id, substs)); + return Ok(()); } let def_key = cx.tcx.def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - p!(write("{}", name))?; + p!(write("{}", name)); let mut substs = substs.iter(); // FIXME(eddyb) print this with `print_def_path`. if let Some(first) = substs.next() { - p!(write("::<"))?; - p!(write("{}", first))?; + p!(write("::<")); + p!(write("{}", first)); for subst in substs { - p!(write(", {}", subst))?; + p!(write(", {}", subst)); } - p!(write(">"))?; + p!(write(">")); } return Ok(()); } @@ -1172,7 +1162,7 @@ define_print! { let mut first = true; let mut is_sized = false; - p!(write("impl"))?; + p!(write("impl")); for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. @@ -1183,30 +1173,29 @@ define_print! { p!( write("{}", if first { " " } else { "+" }), - print(trait_ref))?; + print(trait_ref)); first = false; } } if !is_sized { - p!(write("{}?Sized", if first { " " } else { "+" }))?; + p!(write("{}?Sized", if first { " " } else { "+" })); } else if first { - p!(write(" Sized"))?; + p!(write(" Sized")); } - Ok(()) } Str => p!(write("str")), Generator(did, substs, movability) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); let witness = substs.witness(did, cx.tcx); if movability == hir::GeneratorMovability::Movable { - p!(write("[generator"))?; + p!(write("[generator")); } else { - p!(write("[static generator"))?; + p!(write("[static generator")); } // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { - p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; + p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { @@ -1214,7 +1203,7 @@ define_print! { write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; + print(upvar_ty)); sep = ", "; } Ok(()) @@ -1222,12 +1211,12 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did))?; + p!(write("@{:?}", did)); let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { p!( write("{}{}:", sep, index), - print(upvar_ty))?; + print(upvar_ty)); sep = ", "; } } @@ -1235,18 +1224,18 @@ define_print! { p!(write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { - cx.in_binder(&types) + cx.in_binder(&types)? } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); - p!(write("[closure"))?; + p!(write("[closure")); // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { if cx.tcx.sess.opts.debugging_opts.span_free_formats { - p!(write("@{:?}", hir_id))?; + p!(write("@{:?}", hir_id)); } else { - p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; + p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); } let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { @@ -1255,7 +1244,7 @@ define_print! { write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; + print(upvar_ty)); sep = ", "; } Ok(()) @@ -1263,38 +1252,38 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did))?; + p!(write("@{:?}", did)); let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { p!( write("{}{}:", sep, index), - print(upvar_ty))?; + print(upvar_ty)); sep = ", "; } } - if cx.is_verbose { + if cx.config.is_verbose { p!(write( " closure_kind_ty={:?} closure_sig_ty={:?}", substs.closure_kind_ty(did, cx.tcx), substs.closure_sig_ty(did, cx.tcx) - ))?; + )); } p!(write("]")) }, Array(ty, sz) => { - p!(write("["), print(ty), write("; "))?; + p!(write("["), print(ty), write("; ")); match sz { ty::LazyConst::Unevaluated(_def_id, _substs) => { - p!(write("_"))?; + p!(write("_")); } ty::LazyConst::Evaluated(c) => { match c.val { - ConstValue::Infer(..) => p!(write("_"))?, + ConstValue::Infer(..) => p!(write("_")), ConstValue::Param(ParamConst { name, .. }) => - p!(write("{}", name))?, - _ => p!(write("{}", c.unwrap_usize(cx.tcx)))?, + p!(write("{}", name)), + _ => p!(write("{}", c.unwrap_usize(cx.tcx))), } } } @@ -1306,7 +1295,7 @@ define_print! { } } debug { - self.print_display(cx) + p!(print_display(self)) } } } @@ -1423,7 +1412,6 @@ define_print! { Namespace::TypeNS, iter::empty(), )?; - Ok(()) } } } @@ -1444,14 +1432,14 @@ define_print! { ('tcx) ty::Predicate<'tcx>, (self, cx) { display { match *self { - ty::Predicate::Trait(ref data) => data.print(cx), - ty::Predicate::Subtype(ref predicate) => predicate.print(cx), - ty::Predicate::RegionOutlives(ref predicate) => predicate.print(cx), - ty::Predicate::TypeOutlives(ref predicate) => predicate.print(cx), - ty::Predicate::Projection(ref predicate) => predicate.print(cx), + ty::Predicate::Trait(ref data) => p!(print(data)), + ty::Predicate::Subtype(ref predicate) => p!(print(predicate)), + ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::Projection(ref predicate) => p!(print(predicate)), ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { - p!(write("the trait `"))?; + p!(write("the trait `")); let _ = cx.print_def_path( trait_def_id, None, @@ -1461,7 +1449,7 @@ define_print! { p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!(write("the closure `"))?; + p!(write("the closure `")); let _ = cx.print_def_path( closure_def_id, None, @@ -1471,7 +1459,7 @@ define_print! { p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - p!(write("the constant `"))?; + p!(write("the constant `")); let _ = cx.print_def_path( def_id, Some(substs), @@ -1484,12 +1472,12 @@ define_print! { } debug { match *self { - ty::Predicate::Trait(ref a) => a.print(cx), - ty::Predicate::Subtype(ref pair) => pair.print(cx), - ty::Predicate::RegionOutlives(ref pair) => pair.print(cx), - ty::Predicate::TypeOutlives(ref pair) => pair.print(cx), - ty::Predicate::Projection(ref pair) => pair.print(cx), - ty::Predicate::WellFormed(ty) => ty.print(cx), + ty::Predicate::Trait(ref a) => p!(print(a)), + ty::Predicate::Subtype(ref pair) => p!(print(pair)), + ty::Predicate::RegionOutlives(ref pair) => p!(print(pair)), + ty::Predicate::TypeOutlives(ref pair) => p!(print(pair)), + ty::Predicate::Projection(ref pair) => p!(print(pair)), + ty::Predicate::WellFormed(ty) => p!(print(ty)), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("ObjectSafe({:?})", trait_def_id)) } From 7c4eecef0b256850166fdb0070568544f2380115 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 10 Jan 2019 13:27:11 +0200 Subject: [PATCH 121/157] rustc: pass ty::print::PrintCx by value. --- src/librustc/infer/error_reporting/mod.rs | 37 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/print.rs | 387 ++++++++++++++------- src/librustc/util/ppaux.rs | 205 ++++++----- src/librustc_codegen_utils/symbol_names.rs | 117 ++++--- src/librustdoc/clean/mod.rs | 54 ++- 6 files changed, 498 insertions(+), 304 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 68b2d201fb00a..6b1fea581e60f 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -459,37 +459,52 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Path = Vec; fn path_crate( - self: &mut PrintCx<'_, '_, '_, Self>, + self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified<'tcx>( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - _impl_prefix: Option, + self: PrintCx<'_, '_, 'tcx, Self>, _self_ty: Ty<'tcx>, _trait_ref: Option>, _ns: Namespace, ) -> Result { Err(NonTrivialPath) } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + _print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + _self_ty: Ty<'tcx>, + _trait_ref: Option>, + ) -> Result { + Err(NonTrivialPath) + } + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, text: &str, ) -> Result { + let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args<'tcx>( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - path: Self::Path, + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, _params: &[ty::GenericParamDef], _substs: SubstsRef<'tcx>, _ns: Namespace, _projections: impl Iterator>, ) -> Result { - Ok(path) + print_prefix(self) } } @@ -498,7 +513,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { - PrintCx::with(self.tcx, AbsolutePathPrinter, |mut cx| { + PrintCx::with(self.tcx, AbsolutePathPrinter, |cx| { cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) }) }; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 7ee8eec11ee42..70ebb7111ef7a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,7 +2369,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter { fmt }, |cx| { + ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt), |cx| { let region = if cx.config.is_verbose || cx.config.identify_regions { let mut region = region.to_string(); if region.len() > 0 { diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 005dd18177d23..986d65b2d9b6a 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -88,7 +88,7 @@ pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub(crate) config: &'a mut PrintConfig, } -// HACK(eddyb) this is solely for `self: &mut PrintCx`, e.g. to +// HACK(eddyb) this is solely for `self: PrintCx`, e.g. to // implement traits on the printer and call the methods on the context. impl

Deref for PrintCx<'_, '_, '_, P> { type Target = P; @@ -127,21 +127,29 @@ pub trait Print<'tcx, P> { type Output; type Error; - fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result; fn print_display( &self, - cx: &mut PrintCx<'_, '_, 'tcx, P>, + cx: PrintCx<'_, '_, 'tcx, P>, ) -> Result { let old_debug = cx.config.is_debug; cx.config.is_debug = false; - let result = self.print(cx); + let result = self.print(PrintCx { + tcx: cx.tcx, + printer: cx.printer, + config: cx.config, + }); cx.config.is_debug = old_debug; result } - fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print_debug(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { let old_debug = cx.config.is_debug; cx.config.is_debug = true; - let result = self.print(cx); + let result = self.print(PrintCx { + tcx: cx.tcx, + printer: cx.printer, + config: cx.config, + }); cx.config.is_debug = old_debug; result } @@ -153,7 +161,7 @@ pub trait Printer: Sized { type Path; fn print_def_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, + self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, ns: Namespace, @@ -162,7 +170,7 @@ pub trait Printer: Sized { self.default_print_def_path(def_id, substs, ns, projections) } fn print_impl_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, + self: PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, substs: Option>, ns: Namespace, @@ -173,24 +181,36 @@ pub trait Printer: Sized { } fn path_crate( - self: &mut PrintCx<'_, '_, '_, Self>, + self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result; fn path_qualified( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_prefix: Option, + self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> Result; - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - path: Self::Path, + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result; + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, text: &str, ) -> Result; - fn path_generic_args( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - path: Self::Path, + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, ns: Namespace, @@ -198,13 +218,32 @@ pub trait Printer: Sized { ) -> Result; } -#[must_use] -pub struct PrettyPath { - pub empty: bool, +/// Trait for printers that pretty-print using `fmt::Write` to the printer. +pub trait PrettyPrinter: Printer + fmt::Write { + /// Enter a nested print context, for pretty-printing + /// nested components in some larger context. + fn nest<'a, 'gcx, 'tcx, E>( + self: PrintCx<'a, 'gcx, 'tcx, Self>, + f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result, + ) -> Result, E> { + let printer = f(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + })?; + Ok(PrintCx { + tcx: self.tcx, + printer, + config: self.config, + }) + } } -/// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: Printer + fmt::Write {} +macro_rules! nest { + ($cx:ident, $closure:expr) => { + $cx = $cx.nest($closure)? + } +} impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always @@ -231,7 +270,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let ns = self.guess_def_namespace(def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); - let _ = PrintCx::with(self, FmtPrinter { fmt: &mut s }, |mut cx| { + let _ = PrintCx::with(self, FmtPrinter::new(&mut s), |cx| { cx.print_def_path(def_id, None, ns, iter::empty()) }); s @@ -240,7 +279,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { impl PrintCx<'a, 'gcx, 'tcx, P> { pub fn default_print_def_path( - &mut self, + self, def_id: DefId, substs: Option>, ns: Namespace, @@ -273,48 +312,52 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let generics = substs.map(|_| self.tcx.generics_of(def_id)); let generics_parent = generics.as_ref().and_then(|g| g.parent); let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let path = if let Some(generics_parent_def_id) = generics_parent { - assert_eq!(parent_def_id, generics_parent_def_id); - - // FIXME(eddyb) try to move this into the parent's printing - // logic, instead of doing it when printing the child. - let parent_generics = self.tcx.generics_of(parent_def_id); - let parent_has_own_self = - parent_generics.has_self && parent_generics.parent_count == 0; - if let (Some(substs), true) = (substs, parent_has_own_self) { - let trait_ref = ty::TraitRef::new(parent_def_id, substs); - self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns)? + let print_parent_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + if let Some(generics_parent_def_id) = generics_parent { + assert_eq!(parent_def_id, generics_parent_def_id); + + // FIXME(eddyb) try to move this into the parent's printing + // logic, instead of doing it when printing the child. + let parent_generics = cx.tcx.generics_of(parent_def_id); + let parent_has_own_self = + parent_generics.has_self && parent_generics.parent_count == 0; + if let (Some(substs), true) = (substs, parent_has_own_self) { + let trait_ref = ty::TraitRef::new(parent_def_id, substs); + cx.path_qualified(trait_ref.self_ty(), Some(trait_ref), ns) + } else { + cx.print_def_path(parent_def_id, substs, ns, iter::empty()) + } } else { - self.print_def_path(parent_def_id, substs, ns, iter::empty())? + cx.print_def_path(parent_def_id, None, ns, iter::empty()) } - } else { - self.print_def_path(parent_def_id, None, ns, iter::empty())? }; - let path = match key.disambiguated_data.data { - // Skip `::{{constructor}}` on tuple/unit structs. - DefPathData::StructCtor => path, - - _ => { - self.path_append( - path, - &key.disambiguated_data.data.as_interned_str().as_str(), - )? + let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + match key.disambiguated_data.data { + // Skip `::{{constructor}}` on tuple/unit structs. + DefPathData::StructCtor => print_parent_path(cx), + + _ => { + cx.path_append( + print_parent_path, + &key.disambiguated_data.data.as_interned_str().as_str(), + ) + } } }; if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(path, params, substs, ns, projections) + self.path_generic_args(print_path, params, substs, ns, projections) } else { - Ok(path) + print_path(self) } } } } fn default_print_impl_path( - &mut self, + self, impl_def_id: DefId, _substs: Option>, ns: Namespace, @@ -339,18 +382,20 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), }; - let prefix_path = if !in_self_mod && !in_trait_mod { + if !in_self_mod && !in_trait_mod { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - Some(self.print_def_path(parent_def_id, None, ns, iter::empty())?) + self.path_append_impl( + |cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()), + self_ty, + impl_trait_ref, + ) } else { // Otherwise, try to give a good form that would be valid language // syntax. Preferably using associated item notation. - None - }; - - self.path_qualified(prefix_path, self_ty, impl_trait_ref, ns) + self.path_qualified(self_ty, impl_trait_ref, ns) + } } } @@ -403,14 +448,27 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { } pub struct FmtPrinter { - pub fmt: F, + pub(crate) fmt: F, + empty: bool, } -impl PrintCx<'a, 'gcx, 'tcx, P> { +impl FmtPrinter { + pub fn new(fmt: F) -> Self { + FmtPrinter { + fmt, + empty: true, + } + } +} + +impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path(&mut self, def_id: DefId) -> Result, P::Error> { + fn try_print_visible_def_path( + mut self, + def_id: DefId, + ) -> Result<(P, bool), P::Error> { debug!("try_print_visible_def_path: def_id={:?}", def_id); // If `def_id` is a direct or injected extern crate, return the @@ -419,7 +477,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let cnum = def_id.krate; if cnum == LOCAL_CRATE { - return Ok(Some(self.path_crate(cnum)?)); + return Ok((self.path_crate(cnum)?, true)); } // In local mode, when we encounter a crate other than @@ -440,22 +498,21 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { .. }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); - let path = if !span.is_dummy() { + return Ok((if !span.is_dummy() { self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())? } else { self.path_crate(cnum)? - }; - return Ok(Some(path)); + }, true)); } None => { - return Ok(Some(self.path_crate(cnum)?)); + return Ok((self.path_crate(cnum)?, true)); } _ => {}, } } if def_id.is_local() { - return Ok(None); + return Ok((self.printer, false)); } let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); @@ -475,11 +532,20 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let visible_parent = match visible_parent_map.get(&def_id).cloned() { Some(parent) => parent, - None => return Ok(None), + None => return Ok((self.printer, false)), }; - let path = match self.try_print_visible_def_path(visible_parent)? { - Some(path) => path, - None => return Ok(None), + // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether + // the entire path will succeed or not. To support printers that do not + // implement `PrettyPrinter`, a `Vec` or linked list on the stack would + // need to be built, before starting to print anything. + let mut prefix_success = false; + nest!(self, |cx| { + let (printer, success) = cx.try_print_visible_def_path(visible_parent)?; + prefix_success = success; + Ok(printer) + }); + if !prefix_success { + return Ok((self.printer, false)); }; let actual_parent = self.tcx.parent(def_id); @@ -541,29 +607,15 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }, }; debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok(Some(self.path_append(path, &symbol)?)) + Ok((self.path_append(|cx| Ok(cx.printer), &symbol)?, true)) } pub fn pretty_path_qualified( - &mut self, - impl_prefix: Option, + mut self, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> Result { - if let Some(prefix) = impl_prefix { - // HACK(eddyb) going through `path_append` means symbol name - // computation gets to handle its equivalent of `::` correctly. - let _ = self.path_append(prefix, "")?; - return Ok(PrettyPath { empty: false }); - } - if trait_ref.is_none() { // Inherent impls. Try to print `Foo::bar` for an inherent // impl on `Foo`, but fallback to `::bar` if self-type is @@ -578,8 +630,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { - self_ty.print_display(self)?; - return Ok(PrettyPath { empty: false }); + return self_ty.print_display(self); } _ => {} @@ -587,28 +638,54 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } write!(self.printer, "<")?; - self_ty.print_display(self)?; + nest!(self, |cx| self_ty.print_display(cx)); if let Some(trait_ref) = trait_ref { write!(self.printer, " as ")?; - let _ = self.print_def_path( + nest!(self, |cx| cx.print_def_path( trait_ref.def_id, Some(trait_ref.substs), Namespace::TypeNS, iter::empty(), - )?; + )); } write!(self.printer, ">")?; - Ok(PrettyPath { empty: false }) + + Ok(self.printer) + } + + pub fn pretty_path_append_impl( + mut self, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, P>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + // HACK(eddyb) going through `path_append` means symbol name + // computation gets to handle its equivalent of `::` correctly. + nest!(self, |cx| cx.path_append(print_prefix, "")?; + + Ok(self.printer) } pub fn pretty_path_generic_args( - &mut self, - path: P::Path, + mut self, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, P>, + ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, ) -> Result { + nest!(self, |cx| print_prefix(cx)); + let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { write!(cx.printer, "{}", if empty { @@ -652,8 +729,8 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { if !print_regions { continue; } - start_or_continue(self, start, ", ")?; - if !region.display_outputs_anything(self) { + start_or_continue(&mut self, start, ", ")?; + if !region.display_outputs_anything(&self) { // This happens when the value of the region // parameter is not easily serialized. This may be // because the user omitted it in the first place, @@ -661,12 +738,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // etc. I'm not sure how best to serialize this. write!(self.printer, "'_")?; } else { - region.print_display(self)?; + nest!(self, |cx| region.print_display(cx)); } } UnpackedKind::Type(ty) => { - start_or_continue(self, start, ", ")?; - ty.print_display(self)?; + start_or_continue(&mut self, start, ", ")?; + nest!(self, |cx| ty.print_display(cx)); } UnpackedKind::Const(ct) => { start_or_continue(self, start, ", ")?; @@ -676,20 +753,21 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } for projection in projections { - start_or_continue(self, start, ", ")?; + start_or_continue(&mut self, start, ", ")?; write!(self.printer, "{}=", self.tcx.associated_item(projection.item_def_id).ident)?; - projection.ty.print_display(self)?; + nest!(self, |cx| projection.ty.print_display(cx)); } - start_or_continue(self, "", ">")?; + start_or_continue(&mut self, "", ">")?; - Ok(path) + Ok(self.printer) } } impl fmt::Write for FmtPrinter { fn write_str(&mut self, s: &str) -> fmt::Result { + self.empty &= s.is_empty(); self.fmt.write_str(s) } } @@ -697,10 +775,10 @@ impl fmt::Write for FmtPrinter { impl Printer for FmtPrinter { type Error = fmt::Error; - type Path = PrettyPath; + type Path = Self; fn print_def_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, + mut self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, ns: Namespace, @@ -710,15 +788,20 @@ impl Printer for FmtPrinter { // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); if generics.as_ref().and_then(|g| g.parent).is_none() { - if let Some(path) = self.try_print_visible_def_path(def_id)? { - let path = if let (Some(generics), Some(substs)) = (generics, substs) { + let mut visible_path_success = false; + nest!(self, |cx| { + let (printer, success) = cx.try_print_visible_def_path(def_id)?; + visible_path_success = success; + Ok(printer) + }); + if visible_path_success { + return if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(path, params, substs, ns, projections)? + self.path_generic_args(|cx| Ok(cx.printer), params, substs, ns, projections) } else { - path + Ok(self.printer) }; - return Ok(path); } } @@ -738,9 +821,11 @@ impl Printer for FmtPrinter { // pretty printing some span information. This should // only occur very early in the compiler pipeline. let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let path = self.print_def_path(parent_def_id, None, ns, iter::empty())?; let span = self.tcx.def_span(def_id); - return self.path_append(path, &format!("", span)); + return self.path_append( + |cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()), + &format!("", span), + ); } } @@ -748,7 +833,7 @@ impl Printer for FmtPrinter { } fn path_crate( - self: &mut PrintCx<'_, '_, '_, Self>, + mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { if cnum == LOCAL_CRATE { @@ -756,51 +841,83 @@ impl Printer for FmtPrinter { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { write!(self.printer, "{}", keywords::Crate.name())?; - return Ok(PrettyPath { empty: false }); } } - Ok(PrettyPath { empty: true }) + Ok(self.printer) } else { write!(self.printer, "{}", self.tcx.crate_name(cnum))?; - Ok(PrettyPath { empty: false }) + Ok(self.printer) } } fn path_qualified( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_prefix: Option, + self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> Result { - self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns) + self.pretty_path_qualified(self_ty, trait_ref, ns) } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - path: Self::Path, + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self.pretty_path_append_impl(print_prefix, self_ty, trait_ref) + } + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, text: &str, ) -> Result { - // FIXME(eddyb) this shouldn't happen, but is currently - // the case for `extern { ... }` "foreign modules". - if text.is_empty() { - return Ok(path); - } + let mut printer = print_prefix(self)?; - if !path.empty { - write!(self.printer, "::")?; + // FIXME(eddyb) `text` should never be empty, but it + // currently is for `extern { ... }` "foreign modules". + if !text.is_empty() { + if !printer.empty { + write!(printer, "::")?; + } + write!(printer, "{}", text)?; } - write!(self.printer, "{}", text)?; - Ok(PrettyPath { empty: false }) + + Ok(printer) } - fn path_generic_args( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - path: Self::Path, + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, ) -> Result { - self.pretty_path_generic_args(path, params, substs, ns, projections) + self.pretty_path_generic_args(print_prefix, params, substs, ns, projections) } } -impl PrettyPrinter for FmtPrinter {} +impl PrettyPrinter for FmtPrinter { + fn nest<'a, 'gcx, 'tcx, E>( + mut self: PrintCx<'a, 'gcx, 'tcx, Self>, + f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result, + ) -> Result, E> { + let was_empty = std::mem::replace(&mut self.printer.empty, true); + let mut printer = f(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + })?; + printer.empty &= was_empty; + Ok(PrintCx { + tcx: self.tcx, + printer, + config: self.config, + }) + } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 55e0544d2bbe5..ff5d9335909ee 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -161,8 +161,9 @@ impl RegionHighlightMode { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { - $with(&cx.tcx.lift(self).expect("could not lift for printing"), &mut cx) + PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { + $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?; + Ok(()) }) } }; @@ -193,27 +194,35 @@ macro_rules! gen_display_debug { macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { - type Output = (); + type Output = P; type Error = fmt::Error; - fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { - Ok({ + fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + #[allow(unused_mut)] + let mut $cx = $cx; + let _: () = { define_scoped_cx!($cx); + if $cx.config.is_debug $dbg else $disp - }) + }; + Ok($cx.printer) } } }; ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { impl Print<'tcx, P> for $target { - type Output = (); + type Output = P; type Error = fmt::Error; - fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { - Ok({ + fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + #[allow(unused_mut)] + let mut $cx = $cx; + let _: () = { define_scoped_cx!($cx); + if $cx.config.is_debug $dbg else $disp - }) + }; + Ok($cx.printer) } } }; @@ -251,18 +260,23 @@ macro_rules! define_print_multi { $(define_print! { $generic $target, $vars $def })* }; } +macro_rules! nest { + ($closure:expr) => { + scoped_cx!() = scoped_cx!().nest($closure)? + } +} macro_rules! print_inner { (write ($($data:expr),+)) => { - write!(scoped_cx!().printer, $($data),+) + write!(scoped_cx!().printer, $($data),+)? }; ($kind:ident ($data:expr)) => { - $data.$kind(scoped_cx!()) + nest!(|cx| $data.$kind(cx)) }; } macro_rules! p { ($($kind:ident $data:tt),+) => { { - $(print_inner!($kind $data)?);+ + $(print_inner!($kind $data));+ } }; } @@ -277,11 +291,11 @@ macro_rules! define_scoped_cx { impl PrintCx<'a, 'gcx, 'tcx, P> { fn fn_sig( - &mut self, + mut self, inputs: &[Ty<'tcx>], c_variadic: bool, output: Ty<'tcx>, - ) -> fmt::Result { + ) -> Result { define_scoped_cx!(self); p!(write("(")); @@ -300,11 +314,11 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { p!(write(" -> "), print_display(output)); } - Ok(()) + Ok(self.printer) } - fn in_binder(&mut self, value: &ty::Binder) -> Result - where T: Print<'tcx, P, Error = fmt::Error> + TypeFoldable<'tcx> + fn in_binder(mut self, value: &ty::Binder) -> Result + where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx> { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -341,7 +355,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { let old_region_index = self.config.region_index; let mut region_index = old_region_index; let new_value = self.tcx.replace_late_bound_regions(value, |br| { - let _ = start_or_continue(self, "for<", ", "); + let _ = start_or_continue(&mut self, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { let _ = write!(self.printer, "{}", name); @@ -363,12 +377,16 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }; self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) }).0; - start_or_continue(self, "", "> ")?; + start_or_continue(&mut self, "", "> ")?; // Push current state to gcx, and restore after writing new_value. self.config.binder_depth += 1; self.config.region_index = region_index; - let result = new_value.print_display(self); + let result = new_value.print_display(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + }); self.config.region_index = old_region_index; self.config.binder_depth -= 1; result @@ -388,9 +406,9 @@ pub fn parameterized( substs: SubstsRef<'_>, ns: Namespace, ) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - let _ = cx.print_def_path(did, Some(substs), ns, iter::empty())?; + cx.print_def_path(did, Some(substs), ns, iter::empty())?; Ok(()) }) } @@ -410,13 +428,13 @@ define_print! { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( principal.def_id, None, Namespace::TypeNS, iter::empty(), - )?; - cx.fn_sig(args, false, proj.ty)?; + )); + nest!(|cx| cx.fn_sig(args, false, proj.ty)); resugared_principal = true; } } @@ -426,12 +444,12 @@ define_print! { // Use a type that can't appear in defaults of type parameters. let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let principal = principal.with_self_ty(cx.tcx, dummy_self); - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( principal.def_id, Some(principal.substs), Namespace::TypeNS, self.projection_bounds(), - )?; + )); } first = false; } @@ -458,12 +476,12 @@ define_print! { } first = false; - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( def_id, None, Namespace::TypeNS, iter::empty(), - )?; + )); } } } @@ -486,8 +504,8 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { - let _ = cx.print_def_path( + PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { + cx.print_def_path( self.def_id, None, Namespace::TypeNS, @@ -500,8 +518,8 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { - let _ = cx.print_def_path( + PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { + cx.print_def_path( self.did, None, Namespace::TypeNS, @@ -522,7 +540,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter::new(f), |mut cx| { define_scoped_cx!(cx); p!(write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, @@ -571,9 +589,10 @@ define_print! { display { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - p!(print_display(ty::Binder::bind(*self) + let trait_ref = *ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) - .skip_binder())) + .skip_binder(); + p!(print_display(trait_ref)) } debug { p!(print_display(self)) @@ -599,7 +618,7 @@ define_print! { if let BrNamed(_, name) = *self { if name != "" && name != "'_" { p!(write("{}", name)); - return Ok(()); + return Ok(cx.printer); } } @@ -628,7 +647,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::BoundRegion { - fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { if cx.config.is_verbose { return true; } @@ -671,7 +690,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::PlaceholderRegion { - fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { if cx.config.is_verbose { return true; } @@ -695,7 +714,7 @@ define_print! { // Watch out for region highlights. if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { p!(write("'{:?}", n)); - return Ok(()); + return Ok(cx.printer); } // These printouts are concise. They do not contain all the information @@ -798,7 +817,7 @@ define_print! { // NB: this must be kept in sync with the printing logic above. impl ty::RegionKind { // HACK(eddyb) `pub(crate)` only for `ty::print`. - pub(crate) fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { + pub(crate) fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { if cx.config.is_verbose { return true; } @@ -867,7 +886,7 @@ define_print! { } p!(write("fn")); - cx.fn_sig(self.inputs(), self.c_variadic, self.output())? + nest!(|cx| cx.fn_sig(self.inputs(), self.c_variadic, self.output())); } debug { p!(write("({:?}; c_variadic: {})->{:?}", @@ -929,7 +948,7 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::RegionVid { - fn display_outputs_anything

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { if cx.config.is_verbose { return true; } @@ -1011,7 +1030,7 @@ define_print_multi! { ] (self, cx) { display { - cx.in_binder(self)? + nest!(|cx| cx.in_binder(self)) } } } @@ -1019,15 +1038,15 @@ define_print_multi! { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, cx) { display { - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( self.def_id, Some(self.substs), Namespace::TypeNS, iter::empty(), - )?; + )); } debug { - let _ = cx.path_qualified(None, self.self_ty(), Some(*self), Namespace::TypeNS)?; + nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS)); } } } @@ -1050,7 +1069,7 @@ define_print! { } Ref(r, ty, mutbl) => { p!(write("&")); - if r.display_outputs_anything(cx) { + if r.display_outputs_anything(&cx) { p!(print_display(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) @@ -1073,12 +1092,12 @@ define_print! { FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); p!(print(sig), write(" {{")); - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( def_id, Some(substs), Namespace::ValueNS, iter::empty(), - )?; + )); p!(write("}}")) } FnPtr(ref bare_fn) => { @@ -1101,15 +1120,15 @@ define_print! { } } Adt(def, substs) => { - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( def.did, Some(substs), Namespace::TypeNS, iter::empty(), - )?; + )); } Dynamic(data, r) => { - let print_r = r.display_outputs_anything(cx); + let print_r = r.display_outputs_anything(&cx); if print_r { p!(write("(")); } @@ -1119,18 +1138,16 @@ define_print! { } } Foreign(def_id) => { - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( def_id, None, Namespace::TypeNS, iter::empty(), - )?; + )); } Projection(ref data) => p!(print(data)), UnnormalizedProjection(ref data) => { - p!(write("Unnormalized(")); - data.print(cx)?; - p!(write(")")) + p!(write("Unnormalized("), print(data), write(")")) } Placeholder(placeholder) => { p!(write("Placeholder({:?})", placeholder)) @@ -1138,7 +1155,7 @@ define_print! { Opaque(def_id, substs) => { if cx.config.is_verbose { p!(write("Opaque({:?}, {:?})", def_id, substs)); - return Ok(()); + return Ok(cx.printer); } let def_key = cx.tcx.def_key(def_id); @@ -1154,7 +1171,7 @@ define_print! { } p!(write(">")); } - return Ok(()); + return Ok(cx.printer); } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. @@ -1197,17 +1214,19 @@ define_print! { if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); let mut sep = " "; - cx.tcx.with_freevars(hir_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - p!( - write("{}{}:", - sep, - cx.tcx.hir().name(freevar.var_id())), - print(upvar_ty)); - sep = ", "; - } - Ok(()) - })? + for (freevar, upvar_ty) in cx.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + cx.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. @@ -1224,7 +1243,7 @@ define_print! { p!(write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { - cx.in_binder(&types)? + nest!(|cx| cx.in_binder(&types)) } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); @@ -1238,17 +1257,19 @@ define_print! { p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); } let mut sep = " "; - cx.tcx.with_freevars(hir_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - p!( - write("{}{}:", - sep, - cx.tcx.hir().name(freevar.var_id())), - print(upvar_ty)); - sep = ", "; - } - Ok(()) - })? + for (freevar, upvar_ty) in cx.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + cx.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. @@ -1406,12 +1427,12 @@ define_print! { define_print! { ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { display { - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( self.item_def_id, Some(self.substs), Namespace::TypeNS, iter::empty(), - )?; + )); } } } @@ -1440,32 +1461,32 @@ define_print! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( trait_def_id, None, Namespace::TypeNS, iter::empty(), - )?; + )); p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `")); - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( closure_def_id, None, Namespace::ValueNS, iter::empty(), - )?; + )); p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `")); - let _ = cx.print_def_path( + nest!(|cx| cx.print_def_path( def_id, Some(substs), Namespace::ValueNS, iter::empty(), - )?; + )); p!(write("` can be evaluated")) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 8f4b1d1638a80..2f9627331189f 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -93,7 +93,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::print::{PrettyPath, PrettyPrinter, PrintCx, Printer}; +use rustc::ty::print::{PrettyPrinter, PrintCx, Printer}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -225,9 +225,10 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - PrintCx::with(tcx, SymbolPath::new(tcx), |mut cx| { - let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()); - cx.printer.into_interned() + PrintCx::with(tcx, SymbolPath::new(tcx), |cx| { + cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()) + .unwrap() + .into_interned() }) } @@ -348,7 +349,7 @@ struct SymbolPath { temp_buf: String, strict_naming: bool, - // When `true`, `finalize_pending_component` is a noop. + // When `true`, `finalize_pending_component` isn't used. // This is needed when recursing into `path_qualified`, // or `path_generic_args`, as any nested paths are // logically within one component. @@ -407,18 +408,17 @@ impl SymbolPath { impl Printer for SymbolPath { type Error = fmt::Error; - type Path = PrettyPath; + type Path = Self; fn path_crate( - self: &mut PrintCx<'_, '_, '_, Self>, + mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?; - Ok(PrettyPath { empty: false }) + Ok(self.printer) } fn path_qualified( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_prefix: Option, + mut self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, @@ -429,64 +429,85 @@ impl Printer for SymbolPath { ty::Adt(..) | ty::Foreign(_) | ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) - if impl_prefix.is_none() && trait_ref.is_none() => + if trait_ref.is_none() => { - return self.pretty_path_qualified(None, self_ty, trait_ref, ns); + return self.pretty_path_qualified(self_ty, trait_ref, ns); } _ => {} } - // HACK(eddyb) make sure to finalize the last component of the - // `impl` prefix, to avoid it fusing with the following text. - let impl_prefix = match impl_prefix { - Some(prefix) => { - let mut prefix = self.path_append(prefix, "")?; - - // HACK(eddyb) also avoid an unnecessary `::`. - prefix.empty = true; - - Some(prefix) - } - None => None, - }; - let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); - let r = self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns); - self.printer.keep_within_component = kept_within_component; - r + let mut path = self.pretty_path_qualified(self_ty, trait_ref, ns)?; + path.keep_within_component = kept_within_component; + Ok(path) + } + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + let kept_within_component = self.printer.keep_within_component; + let mut path = self.pretty_path_append_impl( + |cx| { + let mut path = print_prefix(cx)?; + path.keep_within_component = true; + Ok(path) + }, + self_ty, + trait_ref, + )?; + path.keep_within_component = kept_within_component; + Ok(path) } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, text: &str, ) -> Result { - if self.keep_within_component { + let keep_within_component = self.printer.keep_within_component; + + let mut path = print_prefix(self)?; + + if keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. - if !path.empty { - self.printer.write_str("::")?; - } else { - path.empty = text.is_empty(); - } + path.write_str("::")?; } else { - self.printer.finalize_pending_component(); - path.empty = false; + path.finalize_pending_component(); } - self.printer.write_str(text)?; + path.write_str(text)?; Ok(path) } - fn path_generic_args( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - path: Self::Path, + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, ns: Namespace, projections: impl Iterator>, ) -> Result { - let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); - let r = self.pretty_path_generic_args(path, params, substs, ns, projections); - self.printer.keep_within_component = kept_within_component; - r + let kept_within_component = self.printer.keep_within_component; + let mut path = self.pretty_path_generic_args( + |cx| { + let mut path = print_prefix(cx)?; + path.keep_within_component = true; + Ok(path) + }, + params, + substs, + ns, + projections, + )?; + path.keep_within_component = kept_within_component; + Ok(path) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ffdf47db54723..536ee3d58d65f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4235,50 +4235,70 @@ where F: Fn(DefId) -> Def { type Path = Vec; fn path_crate( - self: &mut PrintCx<'_, '_, '_, Self>, + self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_prefix: Option, + self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, _ns: Namespace, ) -> Result { - let mut path = impl_prefix.unwrap_or(vec![]); + // This shouldn't ever be needed, but just in case: + Ok(vec![match trait_ref { + Some(trait_ref) => format!("{:?}", trait_ref), + None => format!("<{}>", self_ty), + }]) + } + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + let mut path = print_prefix(self)?; // This shouldn't ever be needed, but just in case: - if let Some(trait_ref) = trait_ref { - path.push(format!("{:?}", trait_ref)); - } else { - path.push(format!("<{}>", self_ty)); - } + path.push(match trait_ref { + Some(trait_ref) => { + format!("", trait_ref, self_ty) + } + None => format!("", self_ty), + }); Ok(path) } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, text: &str, ) -> Result { + let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - path: Self::Path, + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, _params: &[ty::GenericParamDef], _substs: SubstsRef<'tcx>, _ns: Namespace, _projections: impl Iterator>, ) -> Result { - Ok(path) + print_prefix(self) } } - let names = PrintCx::with(tcx, AbsolutePathPrinter, |mut cx| { + let names = PrintCx::with(tcx, AbsolutePathPrinter, |cx| { cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()).unwrap() }); From cafd83d1d5f81ac1ed74bf97a950120505009a23 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 11 Jan 2019 13:07:01 +0200 Subject: [PATCH 122/157] rustc: don't keep RegionHighlightMode in a thread-local. --- .../infer/error_reporting/need_type_info.rs | 25 +- .../nice_region_error/placeholder_error.rs | 230 ++++++++++-------- src/librustc/ty/print.rs | 106 ++++++++ src/librustc/util/ppaux.rs | 193 +++------------ .../borrow_check/error_reporting.rs | 72 ++++-- .../error_reporting/region_name.rs | 14 +- 6 files changed, 334 insertions(+), 306 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 9e0e48e474118..26deecfdbf0fc 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -3,6 +3,7 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOrigin; use crate::ty::{self, Ty, Infer, TyVar}; +use ty::print::Print; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -64,18 +65,28 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String { + pub fn extract_type_name( + &self, + ty: &'a Ty<'tcx>, + highlight: Option, + ) -> String { if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty { let ty_vars = self.type_variables.borrow(); if let TypeVariableOrigin::TypeParameterDefinition(_, name) = *ty_vars.var_origin(ty_vid) { - name.to_string() - } else { - ty.to_string() + return name.to_string(); } - } else { - ty.to_string() } + + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(&mut s); + if let Some(highlight) = highlight { + printer.region_highlight_mode = highlight; + } + let _ = ty::print::PrintCx::with(self.tcx, printer, |cx| { + ty.print(cx) + }); + s } pub fn need_type_info_err(&self, @@ -84,7 +95,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty: Ty<'tcx>) -> DiagnosticBuilder<'gcx> { let ty = self.resolve_type_vars_if_possible(&ty); - let name = self.extract_type_name(&ty); + let name = self.extract_type_name(&ty, None); let mut err_span = span; let mut labels = vec![( diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 189ecf53e0e84..65fcc69a33867 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -5,10 +5,12 @@ use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; -use crate::ty; +use crate::ty::{self, TyCtxt}; use crate::ty::error::ExpectedFound; use crate::ty::subst::SubstsRef; -use crate::util::ppaux::RegionHighlightMode; +use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter}; + +use std::fmt::{self, Write}; impl NiceRegionError<'me, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and @@ -309,13 +311,48 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { sup_placeholder: Option>, has_sub: Option, has_sup: Option, - expected_trait_ref: ty::TraitRef<'_>, - actual_trait_ref: ty::TraitRef<'_>, + expected_trait_ref: ty::TraitRef<'tcx>, + actual_trait_ref: ty::TraitRef<'tcx>, vid: Option>, expected_has_vid: Option, actual_has_vid: Option, any_self_ty_has_vid: bool, ) { + // HACK(eddyb) maybe move this in a more central location. + #[derive(Copy, Clone)] + struct Highlighted<'a, 'gcx, 'tcx, T> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + highlight: RegionHighlightMode, + value: T, + } + + impl<'a, 'gcx, 'tcx, T> Highlighted<'a, 'gcx, 'tcx, T> { + fn map(self, f: impl FnOnce(T) -> U) -> Highlighted<'a, 'gcx, 'tcx, U> { + Highlighted { + tcx: self.tcx, + highlight: self.highlight, + value: f(self.value), + } + } + } + + impl<'tcx, T> fmt::Display for Highlighted<'_, '_, 'tcx, T> + where T: for<'a, 'b> Print<'tcx, + FmtPrinter<&'a mut fmt::Formatter<'b>>, + Error = fmt::Error, + >, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut printer = ty::print::FmtPrinter::new(f); + printer.region_highlight_mode = self.highlight; + + ty::print::PrintCx::with(self.tcx, printer, |cx| { + self.value.print(cx)?; + Ok(()) + }) + } + } + // The weird thing here with the `maybe_highlighting_region` calls and the // the match inside is meant to be like this: // @@ -331,112 +368,93 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { // None, an then we check again inside the closure, but this // setup sort of minimized the number of calls and so form. - RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || { - RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || { - match (has_sub, has_sup) { - (Some(n1), Some(n2)) => { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - )); - } else { - err.note(&format!( - "`{}` must implement `{}`, \ - for any two lifetimes `'{}` and `'{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - )); - } - } - (Some(n), _) | (_, Some(n)) => { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for any lifetime `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - n, - )); - } else { - err.note(&format!( - "`{}` must implement `{}`, for any lifetime `'{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - n, - )); - } - } - (None, None) => RegionHighlightMode::maybe_highlighting_region( - vid, - expected_has_vid, - || { - if let Some(n) = expected_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`, \ - for some specific lifetime `'{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - n, - )); - } else { - if any_self_ty_has_vid { - err.note(&format!( - "`{}` would have to be implemented for the type `{}`", - expected_trait_ref, - expected_trait_ref.self_ty(), - )); - } else { - err.note(&format!( - "`{}` must implement `{}`", - expected_trait_ref.self_ty(), - expected_trait_ref, - )); - } - } - }, - ), - } - }) - }); + let highlight_trait_ref = |trait_ref| Highlighted { + tcx: self.tcx(), + highlight: RegionHighlightMode::default(), + value: trait_ref, + }; - RegionHighlightMode::maybe_highlighting_region( - vid, - actual_has_vid, - || match actual_has_vid { - Some(n) => { - if any_self_ty_has_vid { - err.note(&format!( - "but `{}` is actually implemented for the type `{}`, \ - for some specific lifetime `'{}`", - actual_trait_ref, - actual_trait_ref.self_ty(), - n - )); - } else { - err.note(&format!( - "but `{}` actually implements `{}`, for some specific lifetime `'{}`", - actual_trait_ref.self_ty(), - actual_trait_ref, - n - )); + let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref); + expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub); + expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup); + err.note(&{ + let passive_voice = match (has_sub, has_sup) { + (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid, + (None, None) => { + expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid); + match expected_has_vid { + Some(_) => true, + None => any_self_ty_has_vid, } } + }; - _ => { - err.note(&format!( - "but `{}` is actually implemented for the type `{}`", - actual_trait_ref, - actual_trait_ref.self_ty(), - )); + let mut note = if passive_voice { + format!( + "`{}` would have to be implemented for the type `{}`", + expected_trait_ref, + expected_trait_ref.map(|tr| tr.self_ty()), + ) + } else { + format!( + "`{}` must implement `{}`", + expected_trait_ref.map(|tr| tr.self_ty()), + expected_trait_ref, + ) + }; + + match (has_sub, has_sup) { + (Some(n1), Some(n2)) => { + let _ = write!(note, + ", for any two lifetimes `'{}` and `'{}`", + std::cmp::min(n1, n2), + std::cmp::max(n1, n2), + ); } - }, - ); + (Some(n), _) | (_, Some(n)) => { + let _ = write!(note, + ", for any lifetime `'{}`", + n, + ); + } + (None, None) => if let Some(n) = expected_has_vid { + let _ = write!(note, + ", for some specific lifetime `'{}`", + n, + ); + }, + } + + note + }); + + let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref); + actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid); + err.note(&{ + let passive_voice = match actual_has_vid { + Some(_) => any_self_ty_has_vid, + None => true, + }; + + let mut note = if passive_voice { + format!( + "but `{}` is actually implemented for the type `{}`", + actual_trait_ref, + actual_trait_ref.map(|tr| tr.self_ty()), + ) + } else { + format!( + "but `{}` actually implements `{}`", + actual_trait_ref.map(|tr| tr.self_ty()), + actual_trait_ref, + ) + }; + + if let Some(n) = actual_has_vid { + let _ = write!(note, ", for some specific lifetime `'{}`", n); + } + + note + }); } } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 986d65b2d9b6a..28e21b28f7e44 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -47,6 +47,102 @@ pub fn with_crate_prefix R, R>(f: F) -> R { // FIXME(eddyb) this module uses `pub(crate)` for things used only // from `ppaux` - when that is removed, they can be re-privatized. +/// The "region highlights" are used to control region printing during +/// specific error messages. When a "region highlight" is enabled, it +/// gives an alternate way to print specific regions. For now, we +/// always print those regions using a number, so something like "`'0`". +/// +/// Regions not selected by the region highlight mode are presently +/// unaffected. +#[derive(Copy, Clone, Default)] +pub struct RegionHighlightMode { + /// If enabled, when we see the selected region, use "`'N`" + /// instead of the ordinary behavior. + highlight_regions: [Option<(ty::RegionKind, usize)>; 3], + + /// If enabled, when printing a "free region" that originated from + /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily + /// have names print as normal. + /// + /// This is used when you have a signature like `fn foo(x: &u32, + /// y: &'a u32)` and we want to give a name to the region of the + /// reference `x`. + pub(crate) highlight_bound_region: Option<(ty::BoundRegion, usize)>, +} + +impl RegionHighlightMode { + /// If `region` and `number` are both `Some`, invokes + /// `highlighting_region`. + pub fn maybe_highlighting_region( + &mut self, + region: Option>, + number: Option, + ) { + if let Some(k) = region { + if let Some(n) = number { + self.highlighting_region(k, n); + } + } + } + + /// Highlights the region inference variable `vid` as `'N`. + pub fn highlighting_region( + &mut self, + region: ty::Region<'_>, + number: usize, + ) { + let num_slots = self.highlight_regions.len(); + let first_avail_slot = self.highlight_regions.iter_mut() + .filter(|s| s.is_none()) + .next() + .unwrap_or_else(|| { + bug!( + "can only highlight {} placeholders at a time", + num_slots, + ) + }); + *first_avail_slot = Some((*region, number)); + } + + /// Convenience wrapper for `highlighting_region`. + pub fn highlighting_region_vid( + &mut self, + vid: ty::RegionVid, + number: usize, + ) { + self.highlighting_region(&ty::ReVar(vid), number) + } + + /// Returns `Some(n)` with the number to use for the given region, if any. + pub(crate) fn region_highlighted(&self, region: ty::Region<'_>) -> Option { + self + .highlight_regions + .iter() + .filter_map(|h| match h { + Some((r, n)) if r == region => Some(*n), + _ => None, + }) + .next() + } + + /// Highlight the given bound region. + /// We can only highlight one bound region at a time. See + /// the field `highlight_bound_region` for more detailed notes. + pub fn highlighting_bound_region( + &mut self, + br: ty::BoundRegion, + number: usize, + ) { + assert!(self.highlight_bound_region.is_none()); + self.highlight_bound_region = Some((br, number)); + } + + /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`". + pub(crate) fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { + self.region_highlighted(&ty::RePlaceholder(p)) + } +} + struct LateBoundRegionNameCollector(FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { @@ -237,6 +333,10 @@ pub trait PrettyPrinter: Printer + fmt::Write { config: self.config, }) } + + fn region_highlight_mode(&self) -> RegionHighlightMode { + RegionHighlightMode::default() + } } macro_rules! nest { @@ -450,6 +550,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { pub struct FmtPrinter { pub(crate) fmt: F, empty: bool, + pub region_highlight_mode: RegionHighlightMode, } impl FmtPrinter { @@ -457,6 +558,7 @@ impl FmtPrinter { FmtPrinter { fmt, empty: true, + region_highlight_mode: RegionHighlightMode::default(), } } } @@ -920,4 +1022,8 @@ impl PrettyPrinter for FmtPrinter { config: self.config, }) } + + fn region_highlight_mode(&self) -> RegionHighlightMode { + self.region_highlight_mode + } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ff5d9335909ee..d4111e0375f16 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -12,7 +12,6 @@ use crate::ty::{self, ParamConst, Ty, TypeFoldable}; use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; use crate::mir::interpret::ConstValue; -use std::cell::Cell; use std::fmt::{self, Write as _}; use std::iter; use std::usize; @@ -22,142 +21,6 @@ use syntax::ast::CRATE_NODE_ID; use syntax::symbol::{Symbol, InternedString}; use crate::hir; -/// The "region highlights" are used to control region printing during -/// specific error messages. When a "region highlight" is enabled, it -/// gives an alternate way to print specific regions. For now, we -/// always print those regions using a number, so something like "`'0`". -/// -/// Regions not selected by the region highlight mode are presently -/// unaffected. -#[derive(Copy, Clone, Default)] -pub struct RegionHighlightMode { - /// If enabled, when we see the selected region, use "`'N`" - /// instead of the ordinary behavior. - highlight_regions: [Option<(ty::RegionKind, usize)>; 3], - - /// If enabled, when printing a "free region" that originated from - /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily - /// have names print as normal. - /// - /// This is used when you have a signature like `fn foo(x: &u32, - /// y: &'a u32)` and we want to give a name to the region of the - /// reference `x`. - highlight_bound_region: Option<(ty::BoundRegion, usize)>, -} - -thread_local! { - /// Mechanism for highlighting of specific regions for display in NLL region inference errors. - /// Contains region to highlight and counter for number to use when highlighting. - static REGION_HIGHLIGHT_MODE: Cell = - Cell::new(RegionHighlightMode::default()) -} - -impl RegionHighlightMode { - /// Reads and returns the current region highlight settings (accesses thread-local state). - pub fn get() -> Self { - REGION_HIGHLIGHT_MODE.with(|c| c.get()) - } - - // Internal helper to update current settings during the execution of `op`. - fn set( - old_mode: Self, - new_mode: Self, - op: impl FnOnce() -> R, - ) -> R { - REGION_HIGHLIGHT_MODE.with(|c| { - c.set(new_mode); - let result = op(); - c.set(old_mode); - result - }) - } - - /// If `region` and `number` are both `Some`, invokes - /// `highlighting_region`; otherwise, just invokes `op` directly. - pub fn maybe_highlighting_region( - region: Option>, - number: Option, - op: impl FnOnce() -> R, - ) -> R { - if let Some(k) = region { - if let Some(n) = number { - return Self::highlighting_region(k, n, op); - } - } - - op() - } - - /// During the execution of `op`, highlights the region inference - /// variable `vid` as `'N`. We can only highlight one region `vid` - /// at a time. - pub fn highlighting_region( - region: ty::Region<'_>, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - let old_mode = Self::get(); - let mut new_mode = old_mode; - let first_avail_slot = new_mode.highlight_regions.iter_mut() - .filter(|s| s.is_none()) - .next() - .unwrap_or_else(|| { - panic!( - "can only highlight {} placeholders at a time", - old_mode.highlight_regions.len(), - ) - }); - *first_avail_slot = Some((*region, number)); - Self::set(old_mode, new_mode, op) - } - - /// Convenience wrapper for `highlighting_region`. - pub fn highlighting_region_vid( - vid: ty::RegionVid, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - Self::highlighting_region(&ty::ReVar(vid), number, op) - } - - /// Returns `Some(n)` with the number to use for the given region, if any. - fn region_highlighted(&self, region: ty::Region<'_>) -> Option { - Self::get() - .highlight_regions - .iter() - .filter_map(|h| match h { - Some((r, n)) if r == region => Some(*n), - _ => None, - }) - .next() - } - - /// During the execution of `op`, highlight the given bound - /// region. We can only highlight one bound region at a time. See - /// the field `highlight_bound_region` for more detailed notes. - pub fn highlighting_bound_region( - br: ty::BoundRegion, - number: usize, - op: impl FnOnce() -> R, - ) -> R { - let old_mode = Self::get(); - assert!(old_mode.highlight_bound_region.is_none()); - Self::set( - old_mode, - Self { - highlight_bound_region: Some((br, number)), - ..old_mode - }, - op, - ) - } - - /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`". - pub fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { - self.region_highlighted(&ty::RePlaceholder(p)) - } -} - macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -622,7 +485,7 @@ define_print! { } } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if let Some((region, counter)) = highlight.highlight_bound_region { if *self == region { p!(write("'{}", counter)); @@ -647,7 +510,9 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::BoundRegion { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool + where P: PrettyPrinter + { if cx.config.is_verbose { return true; } @@ -658,7 +523,7 @@ impl ty::BoundRegion { } } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if let Some((region, _)) = highlight.highlight_bound_region { if *self == region { return true; @@ -676,7 +541,7 @@ define_print! { return self.print_debug(cx); } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if let Some(counter) = highlight.placeholder_highlight(*self) { p!(write("'{}", counter)); } else { @@ -690,12 +555,14 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::PlaceholderRegion { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool + where P: PrettyPrinter + { if cx.config.is_verbose { return true; } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if highlight.placeholder_highlight(*self).is_some() { return true; } @@ -712,8 +579,8 @@ define_print! { } // Watch out for region highlights. - if let Some(n) = RegionHighlightMode::get().region_highlighted(self) { - p!(write("'{:?}", n)); + if let Some(n) = cx.printer.region_highlight_mode().region_highlighted(self) { + p!(write("'{}", n)); return Ok(cx.printer); } @@ -780,12 +647,12 @@ define_print! { } ty::ReLateBound(binder_id, ref bound_region) => { - p!(write("ReLateBound({:?}, {:?})", - binder_id, - bound_region)) + p!(write("ReLateBound({:?}, ", binder_id), + print_debug(bound_region), + write(")")) } - ty::ReFree(ref fr) => p!(write("{:?}", fr)), + ty::ReFree(ref fr) => p!(print_debug(fr)), ty::ReScope(id) => { p!(write("ReScope({:?})", id)) @@ -794,11 +661,11 @@ define_print! { ty::ReStatic => p!(write("ReStatic")), ty::ReVar(ref vid) => { - p!(write("{:?}", vid)) + p!(print_debug(vid)) } ty::RePlaceholder(placeholder) => { - p!(write("RePlaceholder({:?})", placeholder)) + p!(write("RePlaceholder("), print_debug(placeholder), write(")")) } ty::ReEmpty => p!(write("ReEmpty")), @@ -817,12 +684,14 @@ define_print! { // NB: this must be kept in sync with the printing logic above. impl ty::RegionKind { // HACK(eddyb) `pub(crate)` only for `ty::print`. - pub(crate) fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { + pub(crate) fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool + where P: PrettyPrinter + { if cx.config.is_verbose { return true; } - if RegionHighlightMode::get().region_highlighted(self).is_some() { + if cx.printer.region_highlight_mode().region_highlighted(self).is_some() { return true; } @@ -926,17 +795,17 @@ define_print! { return self.print_debug(cx); } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - p!(write("'{:?}", counter)); + p!(write("'{}", counter)); } } debug { // HACK(eddyb) this is duplicated from `display` printing, // to keep NLL borrowck working even with `-Zverbose`. - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - p!(write("'{:?}", counter)); + p!(write("'{}", counter)); } else { p!(write("'_#{}r", self.index())); } @@ -948,12 +817,14 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::RegionVid { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool { + fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool + where P: PrettyPrinter + { if cx.config.is_verbose { return true; } - let highlight = RegionHighlightMode::get(); + let highlight = cx.printer.region_highlight_mode(); if highlight.region_highlighted(&ty::ReVar(*self)).is_some() { return true; } @@ -1165,9 +1036,9 @@ define_print! { // FIXME(eddyb) print this with `print_def_path`. if let Some(first) = substs.next() { p!(write("::<")); - p!(write("{}", first)); + p!(print_display(first)); for subst in substs { - p!(write(", {}", subst)); + p!(write(", "), print_display(subst)); } p!(write(">")); } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index aa3750946d366..9a80415827e89 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -12,7 +12,7 @@ use rustc::mir::{ TerminatorKind, VarBindingForm, }; use rustc::ty::{self, DefIdTree}; -use rustc::util::ppaux::RegionHighlightMode; +use rustc::ty::print::Print; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; @@ -831,7 +831,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { - let region_name = annotation.emit(&mut err); + let region_name = annotation.emit(self, &mut err); err.span_label( borrow_span, @@ -1875,7 +1875,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn annotate_argument_and_return_for_borrow( &self, borrow: &BorrowData<'tcx>, - ) -> Option> { + ) -> Option> { // Define a fallback for when we can't match a closure. let fallback = || { let is_closure = self.infcx.tcx.is_closure(self.mir_def_id); @@ -2099,7 +2099,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { &self, did: DefId, sig: ty::PolyFnSig<'tcx>, - ) -> Option> { + ) -> Option> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure(did); let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(did)?; @@ -2245,7 +2245,11 @@ enum AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { /// Annotate the provided diagnostic with information about borrow from the fn signature that /// helps explain. - fn emit(&self, diag: &mut DiagnosticBuilder<'_>) -> String { + fn emit( + &self, + cx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + diag: &mut DiagnosticBuilder<'_>, + ) -> String { match self { AnnotatedBorrowFnSignature::Closure { argument_ty, @@ -2253,10 +2257,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } => { diag.span_label( *argument_span, - format!("has type `{}`", self.get_name_for_ty(argument_ty, 0)), + format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)), ); - self.get_region_name_for_ty(argument_ty, 0) + cx.get_region_name_for_ty(argument_ty, 0) } AnnotatedBorrowFnSignature::AnonymousFunction { argument_ty, @@ -2264,10 +2268,10 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { return_ty, return_span, } => { - let argument_ty_name = self.get_name_for_ty(argument_ty, 0); + let argument_ty_name = cx.get_name_for_ty(argument_ty, 0); diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name)); - let return_ty_name = self.get_name_for_ty(return_ty, 0); + let return_ty_name = cx.get_name_for_ty(return_ty, 0); let types_equal = return_ty_name == argument_ty_name; diag.span_label( *return_span, @@ -2286,7 +2290,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { lifetime-syntax.html#lifetime-elision>", ); - self.get_region_name_for_ty(return_ty, 0) + cx.get_region_name_for_ty(return_ty, 0) } AnnotatedBorrowFnSignature::NamedFunction { arguments, @@ -2294,7 +2298,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { return_span, } => { // Region of return type and arguments checked to be the same earlier. - let region_name = self.get_region_name_for_ty(return_ty, 0); + let region_name = cx.get_region_name_for_ty(return_ty, 0); for (_, argument_span) in arguments { diag.span_label(*argument_span, format!("has lifetime `{}`", region_name)); } @@ -2314,10 +2318,15 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } } } +} +impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Return the name of the provided `Ty` (that must be a reference) with a synthesized lifetime /// name where required. fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(&mut s); + // We need to add synthesized lifetimes where appropriate. We do // this by hooking into the pretty printer and telling it to label the // lifetimes without names with the value `'0`. @@ -2327,28 +2336,41 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }), _, _, - ) => RegionHighlightMode::highlighting_bound_region(*br, counter, || ty.to_string()), - _ => ty.to_string(), + ) => printer.region_highlight_mode.highlighting_bound_region(*br, counter), + _ => {} } + + let _ = ty::print::PrintCx::with(self.infcx.tcx, printer, |cx| { + ty.print(cx) + }); + s } /// Returns the name of the provided `Ty` (that must be a reference)'s region with a /// synthesized lifetime name where required. fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { - match ty.sty { - ty::TyKind::Ref(region, _, _) => match region { - ty::RegionKind::ReLateBound(_, br) - | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { - RegionHighlightMode::highlighting_bound_region( - *br, - counter, - || region.to_string(), - ) + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(&mut s); + + let region = match ty.sty { + ty::TyKind::Ref(region, _, _) => { + match region { + ty::RegionKind::ReLateBound(_, br) + | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { + printer.region_highlight_mode.highlighting_bound_region(*br, counter) + } + _ => {} } - _ => region.to_string(), - }, + + region + } _ => bug!("ty for annotation of borrow region is not a reference"), - } + }; + + let _ = ty::print::PrintCx::with(self.infcx.tcx, printer, |cx| { + region.print(cx) + }); + s } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index fdede054e15f3..362214d325712 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -8,7 +8,7 @@ use rustc::infer::InferCtxt; use rustc::mir::Mir; use rustc::ty::subst::{SubstsRef, UnpackedKind}; use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt}; -use rustc::util::ppaux::RegionHighlightMode; +use rustc::ty::print::RegionHighlightMode; use rustc_errors::DiagnosticBuilder; use syntax::ast::Name; use syntax::symbol::keywords; @@ -396,9 +396,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { argument_ty: Ty<'tcx>, counter: &mut usize, ) -> Option { - let type_name = RegionHighlightMode::highlighting_region_vid(needle_fr, *counter, || { - infcx.extract_type_name(&argument_ty) - }); + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(needle_fr, *counter); + let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)); debug!( "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", @@ -680,9 +680,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { return None; } - let type_name = RegionHighlightMode::highlighting_region_vid( - fr, *counter, || infcx.extract_type_name(&return_ty), - ); + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(fr, *counter); + let type_name = infcx.extract_type_name(&return_ty, Some(highlight)); let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir"); From fc914aa88a525eb6d78d0331fc59fa2d0a60b3b6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 Jan 2019 16:26:03 +0200 Subject: [PATCH 123/157] rustc: centralize region printing in ty::RegionKind's Print impl. --- src/librustc/infer/error_reporting/mod.rs | 7 +- src/librustc/ty/error.rs | 17 +- src/librustc/ty/print.rs | 5 - src/librustc/util/ppaux.rs | 222 ++++++---------------- 4 files changed, 72 insertions(+), 179 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 6b1fea581e60f..974b9c59ea42c 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.hir().span_by_hir_id(node), ), _ => ( - format!("the lifetime {} as defined on", fr.bound_region), + format!("the lifetime {} as defined on", region), cm.def_span(self.hir().span_by_hir_id(node)), ), }, @@ -1497,7 +1497,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { var_origin: RegionVariableOrigin, ) -> DiagnosticBuilder<'tcx> { let br_string = |br: ty::BoundRegion| { - let mut s = br.to_string(); + let mut s = match br { + ty::BrNamed(_, name) => name.to_string(), + _ => String::new(), + }; if !s.is_empty() { s.push_str(" "); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 342a6204d7fe4..4a3e814cf476d 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -71,6 +71,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } } + let br_string = |br: ty::BoundRegion| { + match br { + ty::BrNamed(_, name) => format!(" {}", name), + _ => String::new(), + } + }; + match *self { CyclicTy(_) => write!(f, "cyclic type of infinite size"), Mismatch => write!(f, "types differ"), @@ -105,15 +112,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } RegionsInsufficientlyPolymorphic(br, _) => { write!(f, - "expected bound lifetime parameter{}{}, found concrete lifetime", - if br.is_named() { " " } else { "" }, - br) + "expected bound lifetime parameter{}, found concrete lifetime", + br_string(br)) } RegionsOverlyPolymorphic(br, _) => { write!(f, - "expected concrete lifetime, found bound lifetime parameter{}{}", - if br.is_named() { " " } else { "" }, - br) + "expected concrete lifetime, found bound lifetime parameter{}", + br_string(br)) } RegionsPlaceholderMismatch => { write!(f, "one type is more general than the other") diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 28e21b28f7e44..4e1fdf657bd5f 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -136,11 +136,6 @@ impl RegionHighlightMode { assert!(self.highlight_bound_region.is_none()); self.highlight_bound_region = Some((br, number)); } - - /// Returns `Some(N)` if the placeholder `p` is highlighted to print as "`'N`". - pub(crate) fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { - self.region_highlighted(&ty::RePlaceholder(p)) - } } struct LateBoundRegionNameCollector(FxHashSet); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d4111e0375f16..1ac6f3fea4c5a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -2,7 +2,6 @@ use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::middle::region; use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; -use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use crate::ty::{Bool, Char, Adt}; use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; @@ -471,119 +470,34 @@ define_print! { } } -define_print! { - () ty::BoundRegion, (self, cx) { - display { - if cx.config.is_verbose { - return self.print_debug(cx); - } - - if let BrNamed(_, name) = *self { - if name != "" && name != "'_" { - p!(write("{}", name)); - return Ok(cx.printer); - } - } - - let highlight = cx.printer.region_highlight_mode(); - if let Some((region, counter)) = highlight.highlight_bound_region { - if *self == region { - p!(write("'{}", counter)); - } - } - } - debug { - match *self { - BrAnon(n) => p!(write("BrAnon({:?})", n)), - BrFresh(n) => p!(write("BrFresh({:?})", n)), - BrNamed(did, name) => { - p!(write("BrNamed({:?}:{:?}, {})", - did.krate, did.index, name)) - } - BrEnv => p!(write("BrEnv")), - } - } - } -} - -// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) -// -// NB: this must be kept in sync with the printing logic above. -impl ty::BoundRegion { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool - where P: PrettyPrinter - { - if cx.config.is_verbose { - return true; - } - - if let BrNamed(_, name) = *self { - if name != "" && name != "'_" { - return true; - } - } - - let highlight = cx.printer.region_highlight_mode(); - if let Some((region, _)) = highlight.highlight_bound_region { - if *self == region { - return true; +impl fmt::Debug for ty::BoundRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), + ty::BrFresh(n) => write!(f, "BrFresh({:?})", n), + ty::BrNamed(did, name) => { + write!(f, "BrNamed({:?}:{:?}, {})", + did.krate, did.index, name) } + ty::BrEnv => write!(f, "BrEnv"), } - - false } } define_print! { - () ty::PlaceholderRegion, (self, cx) { + () ty::RegionKind, (self, cx) { display { - if cx.config.is_verbose { - return self.print_debug(cx); - } - + // Watch out for region highlights. let highlight = cx.printer.region_highlight_mode(); - if let Some(counter) = highlight.placeholder_highlight(*self) { - p!(write("'{}", counter)); - } else { - p!(print_display(self.name)); + if let Some(n) = highlight.region_highlighted(self) { + p!(write("'{}", n)); + return Ok(cx.printer); } - } - } -} - -// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) -// -// NB: this must be kept in sync with the printing logic above. -impl ty::PlaceholderRegion { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool - where P: PrettyPrinter - { - if cx.config.is_verbose { - return true; - } - - let highlight = cx.printer.region_highlight_mode(); - if highlight.placeholder_highlight(*self).is_some() { - return true; - } - self.name.display_outputs_anything(cx) - } -} - -define_print! { - () ty::RegionKind, (self, cx) { - display { if cx.config.is_verbose { return self.print_debug(cx); } - // Watch out for region highlights. - if let Some(n) = cx.printer.region_highlight_mode().region_highlighted(self) { - p!(write("'{}", n)); - return Ok(cx.printer); - } - // These printouts are concise. They do not contain all the information // the user might want to diagnose an error, but there is basically no way // to fit that into a short string. Hence the recommendation to use @@ -595,11 +509,20 @@ define_print! { } } ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { - p!(print_display(br)) - } - ty::RePlaceholder(p) => { - p!(print_display(p)) + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + p!(write("{}", name)); + return Ok(cx.printer); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + p!(write("'{}", counter)); + } + } } ty::ReScope(scope) if cx.config.identify_regions => { match scope.data { @@ -619,11 +542,9 @@ define_print! { } } ty::ReVar(region_vid) if cx.config.identify_regions => { - p!(print_debug(region_vid)) - } - ty::ReVar(region_vid) => { - p!(print_display(region_vid)) + p!(write("{:?}", region_vid)); } + ty::ReVar(_) => {} ty::ReScope(_) | ty::ReErased => {} ty::ReStatic => p!(write("'static")), @@ -642,14 +563,11 @@ define_print! { } ty::ReClosureBound(ref vid) => { - p!(write("ReClosureBound({:?})", - vid)) + p!(write("ReClosureBound({:?})", vid)) } ty::ReLateBound(binder_id, ref bound_region) => { - p!(write("ReLateBound({:?}, ", binder_id), - print_debug(bound_region), - write(")")) + p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region)) } ty::ReFree(ref fr) => p!(print_debug(fr)), @@ -661,11 +579,11 @@ define_print! { ty::ReStatic => p!(write("ReStatic")), ty::ReVar(ref vid) => { - p!(print_debug(vid)) + p!(write("{:?}", vid)); } ty::RePlaceholder(placeholder) => { - p!(write("RePlaceholder("), print_debug(placeholder), write(")")) + p!(write("RePlaceholder({:?})", placeholder)) } ty::ReEmpty => p!(write("ReEmpty")), @@ -687,11 +605,12 @@ impl ty::RegionKind { pub(crate) fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool where P: PrettyPrinter { - if cx.config.is_verbose { + let highlight = cx.printer.region_highlight_mode(); + if highlight.region_highlighted(self).is_some() { return true; } - if cx.printer.region_highlight_mode().region_highlighted(self).is_some() { + if cx.config.is_verbose { return true; } @@ -701,17 +620,27 @@ impl ty::RegionKind { } ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) => { - br.display_outputs_anything(cx) - } + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } - ty::RePlaceholder(p) => p.display_outputs_anything(cx), + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } ty::ReScope(_) | ty::ReVar(_) if cx.config.identify_regions => true, - ty::ReVar(region_vid) => region_vid.display_outputs_anything(cx), - + ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false, @@ -788,48 +717,9 @@ impl fmt::Debug for ty::FloatVid { } } -define_print! { - () ty::RegionVid, (self, cx) { - display { - if cx.config.is_verbose { - return self.print_debug(cx); - } - - let highlight = cx.printer.region_highlight_mode(); - if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - p!(write("'{}", counter)); - } - } - debug { - // HACK(eddyb) this is duplicated from `display` printing, - // to keep NLL borrowck working even with `-Zverbose`. - let highlight = cx.printer.region_highlight_mode(); - if let Some(counter) = highlight.region_highlighted(&ty::ReVar(*self)) { - p!(write("'{}", counter)); - } else { - p!(write("'_#{}r", self.index())); - } - } - } -} - -// HACK(eddyb) (see `ty::RegionKind::display_outputs_anything`) -// -// NB: this must be kept in sync with the printing logic above. -impl ty::RegionVid { - fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool - where P: PrettyPrinter - { - if cx.config.is_verbose { - return true; - } - - let highlight = cx.printer.region_highlight_mode(); - if highlight.region_highlighted(&ty::ReVar(*self)).is_some() { - return true; - } - - false +impl fmt::Debug for ty::RegionVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'_#{}r", self.index()) } } From 88d96b269c77a0de2c143c797aeb61e928f32e03 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 Jan 2019 17:55:57 +0200 Subject: [PATCH 124/157] rustc: support overriding region printing in ty::print::Printer. --- src/librustc/infer/error_reporting/mod.rs | 8 + src/librustc/ty/print.rs | 174 +++++++++++++++++++-- src/librustc/util/ppaux.rs | 129 +-------------- src/librustc_codegen_utils/symbol_names.rs | 17 +- src/librustdoc/clean/mod.rs | 8 + 5 files changed, 199 insertions(+), 137 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 974b9c59ea42c..768839bf60fdc 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -457,6 +457,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Error = NonTrivialPath; type Path = Vec; + type Region = !; + + fn print_region( + self: PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> Result { + Err(NonTrivialPath) + } fn path_crate( self: PrintCx<'_, '_, '_, Self>, diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 4e1fdf657bd5f..cf47840b022ee 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -1,6 +1,7 @@ use crate::hir::def::Namespace; use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::middle::region; use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; @@ -67,7 +68,7 @@ pub struct RegionHighlightMode { /// This is used when you have a signature like `fn foo(x: &u32, /// y: &'a u32)` and we want to give a name to the region of the /// reference `x`. - pub(crate) highlight_bound_region: Option<(ty::BoundRegion, usize)>, + highlight_bound_region: Option<(ty::BoundRegion, usize)>, } impl RegionHighlightMode { @@ -114,7 +115,7 @@ impl RegionHighlightMode { } /// Returns `Some(n)` with the number to use for the given region, if any. - pub(crate) fn region_highlighted(&self, region: ty::Region<'_>) -> Option { + fn region_highlighted(&self, region: ty::Region<'_>) -> Option { self .highlight_regions .iter() @@ -250,6 +251,7 @@ pub trait Printer: Sized { type Error; type Path; + type Region; fn print_def_path( self: PrintCx<'_, '_, 'tcx, Self>, @@ -271,6 +273,11 @@ pub trait Printer: Sized { self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref) } + fn print_region( + self: PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> Result; + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -310,7 +317,7 @@ pub trait Printer: Sized { } /// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: Printer + fmt::Write { +pub trait PrettyPrinter: Printer + fmt::Write { /// Enter a nested print context, for pretty-printing /// nested components in some larger context. fn nest<'a, 'gcx, 'tcx, E>( @@ -329,9 +336,26 @@ pub trait PrettyPrinter: Printer + fmt::Write { }) } - fn region_highlight_mode(&self) -> RegionHighlightMode { - RegionHighlightMode::default() + /// Return `true` if the region should be printed in path generic args + /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. + fn always_print_region_in_paths( + self: &PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> bool { + false } + + // HACK(eddyb) Trying to print a lifetime might not print anything, which + // may need special handling in the caller (of `ty::RegionKind::print`). + // To avoid printing to a temporary string (which isn't even supported), + // the `print_region_outputs_anything` method can instead be used to + // determine this, ahead of time. + // + // NB: this must be kept in sync with the implementation of `print_region`. + fn print_region_outputs_anything( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool; } macro_rules! nest { @@ -795,10 +819,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; - // Don't print any regions if they're all erased. + // Don't print `'_` if there's no printed region. let print_regions = params.iter().any(|param| { match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(r) => *r != ty::ReErased, + UnpackedKind::Lifetime(r) => { + self.always_print_region_in_paths(r) || + self.print_region_outputs_anything(r) + } _ => false, } }); @@ -827,7 +854,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { continue; } start_or_continue(&mut self, start, ", ")?; - if !region.display_outputs_anything(&self) { + if !self.print_region_outputs_anything(region) { // This happens when the value of the region // parameter is not easily serialized. This may be // because the user omitted it in the first place, @@ -873,6 +900,7 @@ impl Printer for FmtPrinter { type Error = fmt::Error; type Path = Self; + type Region = Self; fn print_def_path( mut self: PrintCx<'_, '_, 'tcx, Self>, @@ -929,6 +957,80 @@ impl Printer for FmtPrinter { self.default_print_def_path(def_id, substs, ns, projections) } + fn print_region( + mut self: PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> Result { + // Watch out for region highlights. + let highlight = self.printer.region_highlight_mode; + if let Some(n) = highlight.region_highlighted(region) { + write!(self.printer, "'{}", n)?; + return Ok(self.printer); + } + + if self.config.is_verbose { + return region.print_debug(self); + } + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *region { + ty::ReEarlyBound(ref data) => { + if data.name != "'_" { + write!(self.printer, "{}", data.name)?; + } + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + write!(self.printer, "{}", name)?; + return Ok(self.printer); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + write!(self.printer, "'{}", counter)?; + } + } + } + ty::ReScope(scope) if self.config.identify_regions => { + match scope.data { + region::ScopeData::Node => + write!(self.printer, "'{}s", scope.item_local_id().as_usize())?, + region::ScopeData::CallSite => + write!(self.printer, "'{}cs", scope.item_local_id().as_usize())?, + region::ScopeData::Arguments => + write!(self.printer, "'{}as", scope.item_local_id().as_usize())?, + region::ScopeData::Destruction => + write!(self.printer, "'{}ds", scope.item_local_id().as_usize())?, + region::ScopeData::Remainder(first_statement_index) => write!(self.printer, + "'{}_{}rs", + scope.item_local_id().as_usize(), + first_statement_index.index() + )?, + } + } + ty::ReVar(region_vid) if self.config.identify_regions => { + write!(self.printer, "{:?}", region_vid)?; + } + ty::ReVar(_) => {} + ty::ReScope(_) | + ty::ReErased => {} + ty::ReStatic => write!(self.printer, "'static")?, + ty::ReEmpty => write!(self.printer, "'")?, + + // The user should never encounter these in unsubstituted form. + ty::ReClosureBound(vid) => write!(self.printer, "{:?}", vid)?, + } + + Ok(self.printer) + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -1018,7 +1120,59 @@ impl PrettyPrinter for FmtPrinter { }) } - fn region_highlight_mode(&self) -> RegionHighlightMode { - self.region_highlight_mode + fn always_print_region_in_paths( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool { + *region != ty::ReErased + } + + fn print_region_outputs_anything( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool { + let highlight = self.printer.region_highlight_mode; + if highlight.region_highlighted(region).is_some() { + return true; + } + + if self.config.is_verbose { + return true; + } + + match *region { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } + + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } + + ty::ReScope(_) | + ty::ReVar(_) if self.config.identify_regions => true, + + ty::ReVar(_) | + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1ac6f3fea4c5a..e14741f55ef19 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,6 +1,5 @@ use crate::hir::def::Namespace; use crate::hir::def_id::DefId; -use crate::middle::region; use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::ty::{Bool, Char, Adt}; use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; @@ -487,72 +486,7 @@ impl fmt::Debug for ty::BoundRegion { define_print! { () ty::RegionKind, (self, cx) { display { - // Watch out for region highlights. - let highlight = cx.printer.region_highlight_mode(); - if let Some(n) = highlight.region_highlighted(self) { - p!(write("'{}", n)); - return Ok(cx.printer); - } - - if cx.config.is_verbose { - return self.print_debug(cx); - } - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *self { - ty::ReEarlyBound(ref data) => { - if data.name != "'_" { - p!(write("{}", data.name)) - } - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - p!(write("{}", name)); - return Ok(cx.printer); - } - } - - if let Some((region, counter)) = highlight.highlight_bound_region { - if br == region { - p!(write("'{}", counter)); - } - } - } - ty::ReScope(scope) if cx.config.identify_regions => { - match scope.data { - region::ScopeData::Node => - p!(write("'{}s", scope.item_local_id().as_usize())), - region::ScopeData::CallSite => - p!(write("'{}cs", scope.item_local_id().as_usize())), - region::ScopeData::Arguments => - p!(write("'{}as", scope.item_local_id().as_usize())), - region::ScopeData::Destruction => - p!(write("'{}ds", scope.item_local_id().as_usize())), - region::ScopeData::Remainder(first_statement_index) => p!(write( - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - )), - } - } - ty::ReVar(region_vid) if cx.config.identify_regions => { - p!(write("{:?}", region_vid)); - } - ty::ReVar(_) => {} - ty::ReScope(_) | - ty::ReErased => {} - ty::ReStatic => p!(write("'static")), - ty::ReEmpty => p!(write("'")), - - // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => p!(write("{:?}", vid)), - } + return cx.print_region(self); } debug { match *self { @@ -594,63 +528,6 @@ define_print! { } } -// HACK(eddyb) Trying to print a lifetime might not print anything, which -// may need special handling in the caller (of `ty::RegionKind::print`). -// To avoid printing to a temporary string, the `display_outputs_anything` -// method can instead be used to determine this, ahead of time. -// -// NB: this must be kept in sync with the printing logic above. -impl ty::RegionKind { - // HACK(eddyb) `pub(crate)` only for `ty::print`. - pub(crate) fn display_outputs_anything

(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool - where P: PrettyPrinter - { - let highlight = cx.printer.region_highlight_mode(); - if highlight.region_highlighted(self).is_some() { - return true; - } - - if cx.config.is_verbose { - return true; - } - - match *self { - ty::ReEarlyBound(ref data) => { - data.name != "" && data.name != "'_" - } - - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - return true; - } - } - - if let Some((region, _)) = highlight.highlight_bound_region { - if br == region { - return true; - } - } - - false - } - - ty::ReScope(_) | - ty::ReVar(_) if cx.config.identify_regions => true, - - ty::ReVar(_) | - ty::ReScope(_) | - ty::ReErased => false, - - ty::ReStatic | - ty::ReEmpty | - ty::ReClosureBound(_) => true, - } - } -} - define_print! { () ty::FreeRegion, (self, cx) { debug { @@ -830,7 +707,7 @@ define_print! { } Ref(r, ty, mutbl) => { p!(write("&")); - if r.display_outputs_anything(&cx) { + if cx.print_region_outputs_anything(r) { p!(print_display(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) @@ -889,7 +766,7 @@ define_print! { )); } Dynamic(data, r) => { - let print_r = r.display_outputs_anything(&cx); + let print_r = cx.print_region_outputs_anything(r); if print_r { p!(write("(")); } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 2f9627331189f..912f8149513c6 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -409,6 +409,14 @@ impl Printer for SymbolPath { type Error = fmt::Error; type Path = Self; + type Region = Self; + + fn print_region( + self: PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> Result { + Ok(self.printer) + } fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, @@ -511,7 +519,14 @@ impl Printer for SymbolPath { } } -impl PrettyPrinter for SymbolPath {} +impl PrettyPrinter for SymbolPath { + fn print_region_outputs_anything( + self: &PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> bool { + false + } +} impl fmt::Write for SymbolPath { fn write_str(&mut self, s: &str) -> fmt::Result { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 536ee3d58d65f..bceae24b1b44f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4233,6 +4233,14 @@ where F: Fn(DefId) -> Def { type Error = !; type Path = Vec; + type Region = (); + + fn print_region( + self: PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> Result { + Ok(()) + } fn path_crate( self: PrintCx<'_, '_, '_, Self>, From 35e5123f5168102eed3b3c8e1d7ab36e6f90d53b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 Jan 2019 19:56:46 +0200 Subject: [PATCH 125/157] rustc: support overriding type printing in ty::print::Printer. --- src/librustc/infer/error_reporting/mod.rs | 8 + src/librustc/ty/print.rs | 28 +- src/librustc/util/ppaux.rs | 483 +++++++++++---------- src/librustc_codegen_utils/symbol_names.rs | 8 + src/librustdoc/clean/mod.rs | 8 + 5 files changed, 295 insertions(+), 240 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 768839bf60fdc..863e10846f4f4 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -458,6 +458,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Path = Vec; type Region = !; + type Type = !; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -466,6 +467,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Err(NonTrivialPath) } + fn print_type<'tcx>( + self: PrintCx<'_, '_, 'tcx, Self>, + _ty: Ty<'tcx>, + ) -> Result { + Err(NonTrivialPath) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index cf47840b022ee..f2f6f2e30fc26 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -252,6 +252,7 @@ pub trait Printer: Sized { type Path; type Region; + type Type; fn print_def_path( self: PrintCx<'_, '_, 'tcx, Self>, @@ -278,6 +279,11 @@ pub trait Printer: Sized { region: ty::Region<'_>, ) -> Result; + fn print_type( + self: PrintCx<'_, '_, 'tcx, Self>, + ty: Ty<'tcx>, + ) -> Result; + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -317,7 +323,15 @@ pub trait Printer: Sized { } /// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: Printer + fmt::Write { +pub trait PrettyPrinter: + Printer< + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + > + + fmt::Write +{ /// Enter a nested print context, for pretty-printing /// nested components in some larger context. fn nest<'a, 'gcx, 'tcx, E>( @@ -870,8 +884,8 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { nest!(self, |cx| ty.print_display(cx)); } UnpackedKind::Const(ct) => { - start_or_continue(self, start, ", ")?; - ct.print_display(self)?; + start_or_continue(&mut self, start, ", ")?; + nest!(self, |cx| ct.print_display(cx)); } } } @@ -901,6 +915,7 @@ impl Printer for FmtPrinter { type Path = Self; type Region = Self; + type Type = Self; fn print_def_path( mut self: PrintCx<'_, '_, 'tcx, Self>, @@ -1031,6 +1046,13 @@ impl Printer for FmtPrinter { Ok(self.printer) } + fn print_type( + self: PrintCx<'_, '_, 'tcx, Self>, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index e14741f55ef19..f42865f55ec84 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,11 +1,6 @@ use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; -use crate::ty::{Bool, Char, Adt}; -use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; -use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; -use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; -use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, ParamConst, Ty, TypeFoldable}; use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; use crate::mir::interpret::ConstValue; @@ -689,269 +684,283 @@ define_print! { } } -define_print! { - ('tcx) ty::Ty<'tcx>, (self, cx) { - display { - match self.sty { - Bool => p!(write("bool")), - Char => p!(write("char")), - Int(t) => p!(write("{}", t.ty_to_string())), - Uint(t) => p!(write("{}", t.ty_to_string())), - Float(t) => p!(write("{}", t.ty_to_string())), - RawPtr(ref tm) => { - p!(write("*{} ", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - })); - p!(print(tm.ty)) +// FIXME(eddyb) move this to `ty::print`. +impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { + pub fn pretty_print_type( + mut self, + ty: Ty<'tcx>, + ) -> Result { + define_scoped_cx!(self); + + match ty.sty { + ty::Bool => p!(write("bool")), + ty::Char => p!(write("char")), + ty::Int(t) => p!(write("{}", t.ty_to_string())), + ty::Uint(t) => p!(write("{}", t.ty_to_string())), + ty::Float(t) => p!(write("{}", t.ty_to_string())), + ty::RawPtr(ref tm) => { + p!(write("*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })); + p!(print(tm.ty)) + } + ty::Ref(r, ty, mutbl) => { + p!(write("&")); + if self.print_region_outputs_anything(r) { + p!(print_display(r), write(" ")); } - Ref(r, ty, mutbl) => { - p!(write("&")); - if cx.print_region_outputs_anything(r) { - p!(print_display(r), write(" ")); + p!(print(ty::TypeAndMut { ty, mutbl })) + } + ty::Never => p!(write("!")), + ty::Tuple(ref tys) => { + p!(write("(")); + let mut tys = tys.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty), write(",")); + if let Some(&ty) = tys.next() { + p!(write(" "), print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } } - p!(print(ty::TypeAndMut { ty, mutbl })) } - Never => p!(write("!")), - Tuple(ref tys) => { - p!(write("(")); - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - p!(print(ty), write(",")); - if let Some(&ty) = tys.next() { - p!(write(" "), print(ty)); - for &ty in tys { - p!(write(", "), print(ty)); - } + p!(write(")")) + } + ty::FnDef(def_id, substs) => { + let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); + p!(print(sig), write(" {{")); + nest!(|cx| cx.print_def_path( + def_id, + Some(substs), + Namespace::ValueNS, + iter::empty(), + )); + p!(write("}}")) + } + ty::FnPtr(ref bare_fn) => { + p!(print(bare_fn)) + } + ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Error => p!(write("[type error]")), + ty::Param(ref param_ty) => p!(write("{}", param_ty)), + ty::Bound(debruijn, bound_ty) => { + match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) } } - p!(write(")")) + + ty::BoundTyKind::Param(p) => p!(write("{}", p)), } - FnDef(def_id, substs) => { - let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); - p!(print(sig), write(" {{")); - nest!(|cx| cx.print_def_path( - def_id, - Some(substs), - Namespace::ValueNS, - iter::empty(), - )); - p!(write("}}")) + } + ty::Adt(def, substs) => { + nest!(|cx| cx.print_def_path( + def.did, + Some(substs), + Namespace::TypeNS, + iter::empty(), + )); + } + ty::Dynamic(data, r) => { + let print_r = self.print_region_outputs_anything(r); + if print_r { + p!(write("(")); } - FnPtr(ref bare_fn) => { - p!(print(bare_fn)) + p!(write("dyn "), print(data)); + if print_r { + p!(write(" + "), print_display(r), write(")")); + } + } + ty::Foreign(def_id) => { + nest!(|cx| cx.print_def_path( + def_id, + None, + Namespace::TypeNS, + iter::empty(), + )); + } + ty::Projection(ref data) => p!(print(data)), + ty::UnnormalizedProjection(ref data) => { + p!(write("Unnormalized("), print(data), write(")")) + } + ty::Placeholder(placeholder) => { + p!(write("Placeholder({:?})", placeholder)) + } + ty::Opaque(def_id, substs) => { + if self.config.is_verbose { + p!(write("Opaque({:?}, {:?})", def_id, substs)); + return Ok(self.printer); } - Infer(infer_ty) => p!(write("{}", infer_ty)), - Error => p!(write("[type error]")), - Param(ref param_ty) => p!(write("{}", param_ty)), - Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - p!(write("^{}", bound_ty.var.index())) - } else { - p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) - } - } - ty::BoundTyKind::Param(p) => p!(write("{}", p)), + let def_key = self.tcx.def_key(def_id); + if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { + p!(write("{}", name)); + let mut substs = substs.iter(); + // FIXME(eddyb) print this with `print_def_path`. + if let Some(first) = substs.next() { + p!(write("::<")); + p!(print_display(first)); + for subst in substs { + p!(write(", "), print_display(subst)); + } + p!(write(">")); } + return Ok(self.printer); } - Adt(def, substs) => { - nest!(|cx| cx.print_def_path( - def.did, - Some(substs), - Namespace::TypeNS, - iter::empty(), - )); - } - Dynamic(data, r) => { - let print_r = cx.print_region_outputs_anything(r); - if print_r { - p!(write("(")); - } - p!(write("dyn "), print(data)); - if print_r { - p!(write(" + "), print_display(r), write(")")); + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); + + let mut first = true; + let mut is_sized = false; + p!(write("impl")); + for predicate in bounds.predicates { + if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { + // Don't print +Sized, but rather +?Sized if absent. + if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + is_sized = true; + continue; + } + + p!( + write("{}", if first { " " } else { "+" }), + print(trait_ref)); + first = false; } } - Foreign(def_id) => { - nest!(|cx| cx.print_def_path( - def_id, - None, - Namespace::TypeNS, - iter::empty(), - )); - } - Projection(ref data) => p!(print(data)), - UnnormalizedProjection(ref data) => { - p!(write("Unnormalized("), print(data), write(")")) + if !is_sized { + p!(write("{}?Sized", if first { " " } else { "+" })); + } else if first { + p!(write(" Sized")); } - Placeholder(placeholder) => { - p!(write("Placeholder({:?})", placeholder)) + } + ty::Str => p!(write("str")), + ty::Generator(did, substs, movability) => { + let upvar_tys = substs.upvar_tys(did, self.tcx); + let witness = substs.witness(did, self.tcx); + if movability == hir::GeneratorMovability::Movable { + p!(write("[generator")); + } else { + p!(write("[static generator")); } - Opaque(def_id, substs) => { - if cx.config.is_verbose { - p!(write("Opaque({:?}, {:?})", def_id, substs)); - return Ok(cx.printer); - } - let def_key = cx.tcx.def_key(def_id); - if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - p!(write("{}", name)); - let mut substs = substs.iter(); - // FIXME(eddyb) print this with `print_def_path`. - if let Some(first) = substs.next() { - p!(write("::<")); - p!(print_display(first)); - for subst in substs { - p!(write(", "), print_display(subst)); - } - p!(write(">")); - } - return Ok(cx.printer); - } - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let bounds = cx.tcx.predicates_of(def_id).instantiate(cx.tcx, substs); - - let mut first = true; - let mut is_sized = false; - p!(write("impl")); - for predicate in bounds.predicates { - if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == cx.tcx.lang_items().sized_trait() { - is_sized = true; - continue; - } - - p!( - write("{}", if first { " " } else { "+" }), - print(trait_ref)); - first = false; - } + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { + p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; } - if !is_sized { - p!(write("{}?Sized", if first { " " } else { "+" })); - } else if first { - p!(write(" Sized")); + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), + print(upvar_ty)); + sep = ", "; } } - Str => p!(write("str")), - Generator(did, substs, movability) => { - let upvar_tys = substs.upvar_tys(did, cx.tcx); - let witness = substs.witness(did, cx.tcx); - if movability == hir::GeneratorMovability::Movable { - p!(write("[generator")); + + p!(write(" "), print(witness), write("]")) + }, + ty::GeneratorWitness(types) => { + nest!(|cx| cx.in_binder(&types)) + } + ty::Closure(did, substs) => { + let upvar_tys = substs.upvar_tys(did, self.tcx); + p!(write("[closure")); + + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { + if self.tcx.sess.opts.debugging_opts.span_free_formats { + p!(write("@{:?}", hir_id)); } else { - p!(write("[static generator")); + p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); } - - // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { - p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); - let mut sep = " "; - for (freevar, upvar_ty) in cx.tcx.freevars(did) - .as_ref() - .map_or(&[][..], |fv| &fv[..]) - .iter() - .zip(upvar_tys) - { - p!( - write("{}{}:", - sep, - cx.tcx.hir().name(freevar.var_id())), + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), print(upvar_ty)); - sep = ", "; - } - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); - sep = ", "; - } + sep = ", "; } + } - p!(write(" "), print(witness), write("]")) - }, - GeneratorWitness(types) => { - nest!(|cx| cx.in_binder(&types)) + if self.config.is_verbose { + p!(write( + " closure_kind_ty={:?} closure_sig_ty={:?}", + substs.closure_kind_ty(did, self.tcx), + substs.closure_sig_ty(did, self.tcx) + )); } - Closure(did, substs) => { - let upvar_tys = substs.upvar_tys(did, cx.tcx); - p!(write("[closure")); - - // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { - if cx.tcx.sess.opts.debugging_opts.span_free_formats { - p!(write("@{:?}", hir_id)); - } else { - p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))); - } - let mut sep = " "; - for (freevar, upvar_ty) in cx.tcx.freevars(did) - .as_ref() - .map_or(&[][..], |fv| &fv[..]) - .iter() - .zip(upvar_tys) - { - p!( - write("{}{}:", - sep, - cx.tcx.hir().name(freevar.var_id())), - print(upvar_ty)); - sep = ", "; - } - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); - sep = ", "; - } - } - if cx.config.is_verbose { - p!(write( - " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, cx.tcx), - substs.closure_sig_ty(did, cx.tcx) - )); + p!(write("]")) + }, + ty::Array(ty, sz) => { + p!(write("["), print(ty), write("; ")); + match sz { + ty::LazyConst::Unevaluated(_def_id, _substs) => { + p!(write("_")); } - - p!(write("]")) - }, - Array(ty, sz) => { - p!(write("["), print(ty), write("; ")); - match sz { - ty::LazyConst::Unevaluated(_def_id, _substs) => { - p!(write("_")); - } - ty::LazyConst::Evaluated(c) => { - match c.val { - ConstValue::Infer(..) => p!(write("_")), - ConstValue::Param(ParamConst { name, .. }) => - p!(write("{}", name)), - _ => p!(write("{}", c.unwrap_usize(cx.tcx))), - } + ty::LazyConst::Evaluated(c) => { + match c.val { + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => + p!(write("{}", name)), + _ => p!(write("{}", c.unwrap_usize(self.tcx))), } } - p!(write("]")) - } - Slice(ty) => { - p!(write("["), print(ty), write("]")) } + p!(write("]")) } + ty::Slice(ty) => { + p!(write("["), print(ty), write("]")) + } + } + + Ok(self.printer) + } +} + +define_print! { + ('tcx) Ty<'tcx>, (self, cx) { + display { + return cx.print_type(self); } debug { p!(print_display(self)) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 912f8149513c6..f3af242582084 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -410,6 +410,7 @@ impl Printer for SymbolPath { type Path = Self; type Region = Self; + type Type = Self; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -418,6 +419,13 @@ impl Printer for SymbolPath { Ok(self.printer) } + fn print_type( + self: PrintCx<'_, '_, 'tcx, Self>, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bceae24b1b44f..13db78cc803aa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4234,6 +4234,7 @@ where F: Fn(DefId) -> Def { type Path = Vec; type Region = (); + type Type = (); fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -4242,6 +4243,13 @@ where F: Fn(DefId) -> Def { Ok(()) } + fn print_type( + self: PrintCx<'_, '_, 'tcx, Self>, + _ty: Ty<'tcx>, + ) -> Result { + Ok(()) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, From ab26b26d3471e5a26e38d9100a272b1c9d013112 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 Jan 2019 22:07:38 +0200 Subject: [PATCH 126/157] rustc: introduce a ty::print::PrettyPrinter helper for printing "<...>". --- src/librustc/ty/print.rs | 181 +++++++++++++-------- src/librustc_codegen_utils/symbol_names.rs | 68 +++----- 2 files changed, 132 insertions(+), 117 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index f2f6f2e30fc26..447f02f42d24d 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -336,7 +336,7 @@ pub trait PrettyPrinter: /// nested components in some larger context. fn nest<'a, 'gcx, 'tcx, E>( self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result, E> { let printer = f(PrintCx { tcx: self.tcx, @@ -350,6 +350,17 @@ pub trait PrettyPrinter: }) } + /// Print `<...>` around what `f` prints. + fn generic_delimiters<'gcx, 'tcx>( + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result { + write!(self.printer, "<")?; + let mut printer = f(self)?; + write!(printer, ">")?; + Ok(printer) + } + /// Return `true` if the region should be printed in path generic args /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. fn always_print_region_in_paths( @@ -746,7 +757,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } pub fn pretty_path_qualified( - mut self, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, @@ -772,20 +783,19 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - write!(self.printer, "<")?; - nest!(self, |cx| self_ty.print_display(cx)); - if let Some(trait_ref) = trait_ref { - write!(self.printer, " as ")?; - nest!(self, |cx| cx.print_def_path( - trait_ref.def_id, - Some(trait_ref.substs), - Namespace::TypeNS, - iter::empty(), - )); - } - write!(self.printer, ">")?; - - Ok(self.printer) + self.generic_delimiters(|mut cx| { + nest!(cx, |cx| self_ty.print_display(cx)); + if let Some(trait_ref) = trait_ref { + write!(cx.printer, " as ")?; + nest!(cx, |cx| cx.print_def_path( + trait_ref.def_id, + Some(trait_ref.substs), + Namespace::TypeNS, + iter::empty(), + )); + } + Ok(cx.printer) + }) } pub fn pretty_path_append_impl( @@ -796,17 +806,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - // HACK(eddyb) going through `path_append` means symbol name - // computation gets to handle its equivalent of `::` correctly. - nest!(self, |cx| cx.path_append(print_prefix, "")?; + nest!(self, print_prefix); - Ok(self.printer) + self.generic_delimiters(|mut cx| { + write!(cx.printer, "impl ")?; + if let Some(trait_ref) = trait_ref { + nest!(cx, |cx| trait_ref.print_display(cx)); + write!(cx.printer, " for ")?; + } + nest!(cx, |cx| self_ty.print_display(cx)); + + Ok(cx.printer) + }) } pub fn pretty_path_generic_args( @@ -821,18 +832,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ) -> Result { nest!(self, |cx| print_prefix(cx)); - let mut empty = true; - let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - write!(cx.printer, "{}", if empty { - empty = false; - start - } else { - cont - }) - }; - - let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; - // Don't print `'_` if there's no printed region. let print_regions = params.iter().any(|param| { match substs[param.index as usize].unpack() { @@ -861,45 +860,75 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }).count() }; - for param in ¶ms[..params.len() - num_supplied_defaults] { - match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(region) => { - if !print_regions { - continue; + let params = ¶ms[..params.len() - num_supplied_defaults]; + let mut args = params.iter().map(|param| { + substs[param.index as usize].unpack() + }).filter(|arg| { + match arg { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + let arg0 = args.next(); + + let mut projections = projections; + let projection0 = projections.next(); + + if arg0.is_none() && projection0.is_none() { + return Ok(self.printer); + } + + // FIXME(eddyb) move this into `generic_delimiters`. + if ns == Namespace::ValueNS { + write!(self.printer, "::")?; + } + + self.generic_delimiters(|mut cx| { + let mut empty = true; + let mut maybe_comma = |cx: &mut Self| { + if empty { + empty = false; + Ok(()) + } else { + write!(cx.printer, ", ") + } + }; + + for arg in arg0.into_iter().chain(args) { + maybe_comma(&mut cx)?; + + match arg { + UnpackedKind::Lifetime(region) => { + if !cx.print_region_outputs_anything(region) { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + write!(cx.printer, "'_")?; + } else { + nest!(cx, |cx| region.print_display(cx)); + } } - start_or_continue(&mut self, start, ", ")?; - if !self.print_region_outputs_anything(region) { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(self.printer, "'_")?; - } else { - nest!(self, |cx| region.print_display(cx)); + UnpackedKind::Type(ty) => { + nest!(cx, |cx| ty.print_display(cx)); + } + UnpackedKind::Const(ct) => { + nest!(cx, |cx| ct.print_display(cx)); } - } - UnpackedKind::Type(ty) => { - start_or_continue(&mut self, start, ", ")?; - nest!(self, |cx| ty.print_display(cx)); - } - UnpackedKind::Const(ct) => { - start_or_continue(&mut self, start, ", ")?; - nest!(self, |cx| ct.print_display(cx)); } } - } - for projection in projections { - start_or_continue(&mut self, start, ", ")?; - write!(self.printer, "{}=", - self.tcx.associated_item(projection.item_def_id).ident)?; - nest!(self, |cx| projection.ty.print_display(cx)); - } + for projection in projection0.into_iter().chain(projections) { + maybe_comma(&mut cx)?; - start_or_continue(&mut self, "", ">")?; + write!(cx.printer, "{}=", + cx.tcx.associated_item(projection.item_def_id).ident)?; + nest!(cx, |cx| projection.ty.print_display(cx)); + } - Ok(self.printer) + Ok(cx.printer) + }) } } @@ -1087,7 +1116,15 @@ impl Printer for FmtPrinter { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self.pretty_path_append_impl(print_prefix, self_ty, trait_ref) + self.pretty_path_append_impl(|cx| { + let mut printer = print_prefix(cx)?; + + if !printer.empty { + write!(printer, "::")?; + } + + Ok(printer) + }, self_ty, trait_ref) } fn path_append<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, @@ -1126,7 +1163,7 @@ impl Printer for FmtPrinter { impl PrettyPrinter for FmtPrinter { fn nest<'a, 'gcx, 'tcx, E>( mut self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result, E> { let was_empty = std::mem::replace(&mut self.printer.empty, true); let mut printer = f(PrintCx { diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index f3af242582084..40dc22309664a 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -434,28 +434,12 @@ impl Printer for SymbolPath { Ok(self.printer) } fn path_qualified( - mut self: PrintCx<'_, '_, 'tcx, Self>, + self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, ns: Namespace, ) -> Result { - // HACK(eddyb) avoid `keep_within_component` for the cases - // that print without `<...>` around `self_ty`. - match self_ty.sty { - ty::Adt(..) | ty::Foreign(_) | - ty::Bool | ty::Char | ty::Str | - ty::Int(_) | ty::Uint(_) | ty::Float(_) - if trait_ref.is_none() => - { - return self.pretty_path_qualified(self_ty, trait_ref, ns); - } - _ => {} - } - - let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); - let mut path = self.pretty_path_qualified(self_ty, trait_ref, ns)?; - path.keep_within_component = kept_within_component; - Ok(path) + self.pretty_path_qualified(self_ty, trait_ref, ns) } fn path_append_impl<'gcx, 'tcx>( @@ -466,18 +450,11 @@ impl Printer for SymbolPath { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - let kept_within_component = self.printer.keep_within_component; - let mut path = self.pretty_path_append_impl( - |cx| { - let mut path = print_prefix(cx)?; - path.keep_within_component = true; - Ok(path) - }, + self.pretty_path_append_impl( + |cx| cx.path_append(print_prefix, ""), self_ty, trait_ref, - )?; - path.keep_within_component = kept_within_component; - Ok(path) + ) } fn path_append<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, @@ -486,11 +463,9 @@ impl Printer for SymbolPath { ) -> Result, text: &str, ) -> Result { - let keep_within_component = self.printer.keep_within_component; - let mut path = print_prefix(self)?; - if keep_within_component { + if path.keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. path.write_str("::")?; } else { @@ -510,20 +485,7 @@ impl Printer for SymbolPath { ns: Namespace, projections: impl Iterator>, ) -> Result { - let kept_within_component = self.printer.keep_within_component; - let mut path = self.pretty_path_generic_args( - |cx| { - let mut path = print_prefix(cx)?; - path.keep_within_component = true; - Ok(path) - }, - params, - substs, - ns, - projections, - )?; - path.keep_within_component = kept_within_component; - Ok(path) + self.pretty_path_generic_args(print_prefix, params, substs, ns, projections) } } @@ -534,6 +496,22 @@ impl PrettyPrinter for SymbolPath { ) -> bool { false } + + fn generic_delimiters<'gcx, 'tcx>( + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result { + write!(self.printer, "<")?; + + let kept_within_component = + mem::replace(&mut self.printer.keep_within_component, true); + let mut path = f(self)?; + path.keep_within_component = kept_within_component; + + write!(path, ">")?; + + Ok(path) + } } impl fmt::Write for SymbolPath { From 5211e37b1dd6b7fc26d919941e958bce8f5815a0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 14 Jan 2019 23:40:53 +0200 Subject: [PATCH 127/157] rustc: don't pass Namespace explicitly, but rather track it in FmtPrinter. --- src/librustc/infer/error_reporting/mod.rs | 5 +- .../infer/error_reporting/need_type_info.rs | 5 +- .../nice_region_error/placeholder_error.rs | 3 +- src/librustc/mir/mod.rs | 3 +- src/librustc/ty/print.rs | 123 ++++++++++-------- src/librustc/util/ppaux.rs | 99 +++----------- src/librustc_codegen_utils/symbol_names.rs | 9 +- .../borrow_check/error_reporting.rs | 5 +- src/librustdoc/clean/mod.rs | 6 +- 9 files changed, 102 insertions(+), 156 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 863e10846f4f4..ad24e15b45a51 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -444,7 +444,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { terr: &TypeError<'tcx>, sp: Span, ) { - use hir::def::Namespace; use hir::def_id::CrateNum; use ty::print::{PrintCx, Printer}; use ty::subst::SubstsRef; @@ -484,7 +483,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self: PrintCx<'_, '_, 'tcx, Self>, _self_ty: Ty<'tcx>, _trait_ref: Option>, - _ns: Namespace, ) -> Result { Err(NonTrivialPath) } @@ -517,7 +515,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> Result, _params: &[ty::GenericParamDef], _substs: SubstsRef<'tcx>, - _ns: Namespace, _projections: impl Iterator>, ) -> Result { print_prefix(self) @@ -530,7 +527,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { PrintCx::with(self.tcx, AbsolutePathPrinter, |cx| { - cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) + cx.print_def_path(def_id, None, iter::empty()) }) }; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 26deecfdbf0fc..2fabbbeadbd9c 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -1,9 +1,10 @@ +use crate::hir::def::Namespace; use crate::hir::{self, Local, Pat, Body, HirId}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOrigin; use crate::ty::{self, Ty, Infer, TyVar}; -use ty::print::Print; +use crate::ty::print::Print; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -79,7 +80,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s); + let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); if let Some(highlight) = highlight { printer.region_highlight_mode = highlight; } diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 65fcc69a33867..39ab244dae1c5 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,4 +1,5 @@ use errors::DiagnosticBuilder; +use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; @@ -343,7 +344,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { >, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut printer = ty::print::FmtPrinter::new(f); + let mut printer = ty::print::FmtPrinter::new(f, Namespace::TypeNS); printer.region_highlight_mode = self.highlight; ty::print::PrintCx::with(self.tcx, printer, |cx| { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 70ebb7111ef7a..c2cafac2d5580 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,7 +2369,8 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt), |cx| { + let ns = Namespace::ValueNS; + ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt, ns), |cx| { let region = if cx.config.is_verbose || cx.config.identify_regions { let mut region = region.to_string(); if region.len() > 0 { diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 447f02f42d24d..a94ae0123d85d 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -258,20 +258,18 @@ pub trait Printer: Sized { self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - ns: Namespace, projections: impl Iterator>, ) -> Result { - self.default_print_def_path(def_id, substs, ns, projections) + self.default_print_def_path(def_id, substs, projections) } fn print_impl_path( self: PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, substs: Option>, - ns: Namespace, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref) + self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref) } fn print_region( @@ -292,7 +290,6 @@ pub trait Printer: Sized { self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, - ns: Namespace, ) -> Result; fn path_append_impl<'gcx, 'tcx>( @@ -317,7 +314,6 @@ pub trait Printer: Sized { ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, - ns: Namespace, projections: impl Iterator>, ) -> Result; } @@ -350,16 +346,20 @@ pub trait PrettyPrinter: }) } + /// Like `print_def_path` but for value paths. + fn print_value_path( + self: PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ) -> Result { + self.print_def_path(def_id, substs, iter::empty()) + } + /// Print `<...>` around what `f` prints. fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, + self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result { - write!(self.printer, "<")?; - let mut printer = f(self)?; - write!(printer, ">")?; - Ok(printer) - } + ) -> Result; /// Return `true` if the region should be printed in path generic args /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. @@ -414,8 +414,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let ns = self.guess_def_namespace(def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); - let _ = PrintCx::with(self, FmtPrinter::new(&mut s), |cx| { - cx.print_def_path(def_id, None, ns, iter::empty()) + let _ = PrintCx::with(self, FmtPrinter::new(&mut s, ns), |cx| { + cx.print_def_path(def_id, None, iter::empty()) }); s } @@ -426,10 +426,9 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { self, def_id: DefId, substs: Option>, - ns: Namespace, projections: impl Iterator>, ) -> Result { - debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); + debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); let key = self.tcx.def_key(def_id); debug!("default_print_def_path: key={:?}", key); @@ -449,7 +448,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { if let Some(substs) = substs { impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); } - self.print_impl_path(def_id, substs, ns, self_ty, impl_trait_ref) + self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } _ => { @@ -467,12 +466,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { let trait_ref = ty::TraitRef::new(parent_def_id, substs); - cx.path_qualified(trait_ref.self_ty(), Some(trait_ref), ns) + cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) } else { - cx.print_def_path(parent_def_id, substs, ns, iter::empty()) + cx.print_def_path(parent_def_id, substs, iter::empty()) } } else { - cx.print_def_path(parent_def_id, None, ns, iter::empty()) + cx.print_def_path(parent_def_id, None, iter::empty()) } }; let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { @@ -492,7 +491,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(print_path, params, substs, ns, projections) + self.path_generic_args(print_path, params, substs, projections) } else { print_path(self) } @@ -504,7 +503,6 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { self, impl_def_id: DefId, _substs: Option>, - ns: Namespace, self_ty: Ty<'tcx>, impl_trait_ref: Option>, ) -> Result { @@ -531,14 +529,14 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // trait-type, then fallback to a format that identifies // the module more clearly. self.path_append_impl( - |cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None, iter::empty()), self_ty, impl_trait_ref, ) } else { // Otherwise, try to give a good form that would be valid language // syntax. Preferably using associated item notation. - self.path_qualified(self_ty, impl_trait_ref, ns) + self.path_qualified(self_ty, impl_trait_ref) } } } @@ -594,14 +592,16 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { pub struct FmtPrinter { pub(crate) fmt: F, empty: bool, + in_value: bool, pub region_highlight_mode: RegionHighlightMode, } impl FmtPrinter { - pub fn new(fmt: F) -> Self { + pub fn new(fmt: F, ns: Namespace) -> Self { FmtPrinter { fmt, empty: true, + in_value: ns == Namespace::ValueNS, region_highlight_mode: RegionHighlightMode::default(), } } @@ -645,7 +645,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok((if !span.is_dummy() { - self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())? + self.print_def_path(def_id, None, iter::empty())? } else { self.path_crate(cnum)? }, true)); @@ -760,20 +760,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self, self_ty: Ty<'tcx>, trait_ref: Option>, - ns: Namespace, ) -> Result { if trait_ref.is_none() { // Inherent impls. Try to print `Foo::bar` for an inherent // impl on `Foo`, but fallback to `::bar` if self-type is // anything other than a simple path. match self_ty.sty { - ty::Adt(adt_def, substs) => { - return self.print_def_path(adt_def.did, Some(substs), ns, iter::empty()); - } - ty::Foreign(did) => { - return self.print_def_path(did, None, ns, iter::empty()); - } - + ty::Adt(..) | ty::Foreign(_) | ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { return self_ty.print_display(self); @@ -787,12 +780,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { nest!(cx, |cx| self_ty.print_display(cx)); if let Some(trait_ref) = trait_ref { write!(cx.printer, " as ")?; - nest!(cx, |cx| cx.print_def_path( - trait_ref.def_id, - Some(trait_ref.substs), - Namespace::TypeNS, - iter::empty(), - )); + nest!(cx, |cx| trait_ref.print_display(cx)); } Ok(cx.printer) }) @@ -827,7 +815,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, - ns: Namespace, projections: impl Iterator>, ) -> Result { nest!(self, |cx| print_prefix(cx)); @@ -878,11 +865,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { return Ok(self.printer); } - // FIXME(eddyb) move this into `generic_delimiters`. - if ns == Namespace::ValueNS { - write!(self.printer, "::")?; - } - self.generic_delimiters(|mut cx| { let mut empty = true; let mut maybe_comma = |cx: &mut Self| { @@ -950,7 +932,6 @@ impl Printer for FmtPrinter { mut self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - ns: Namespace, projections: impl Iterator>, ) -> Result { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` @@ -967,7 +948,7 @@ impl Printer for FmtPrinter { return if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(|cx| Ok(cx.printer), params, substs, ns, projections) + self.path_generic_args(|cx| Ok(cx.printer), params, substs, projections) } else { Ok(self.printer) }; @@ -992,13 +973,13 @@ impl Printer for FmtPrinter { let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; let span = self.tcx.def_span(def_id); return self.path_append( - |cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None, iter::empty()), &format!("", span), ); } } - self.default_print_def_path(def_id, substs, ns, projections) + self.default_print_def_path(def_id, substs, projections) } fn print_region( @@ -1103,9 +1084,8 @@ impl Printer for FmtPrinter { self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, - ns: Namespace, ) -> Result { - self.pretty_path_qualified(self_ty, trait_ref, ns) + self.pretty_path_qualified(self_ty, trait_ref) } fn path_append_impl<'gcx, 'tcx>( @@ -1119,7 +1099,9 @@ impl Printer for FmtPrinter { self.pretty_path_append_impl(|cx| { let mut printer = print_prefix(cx)?; - if !printer.empty { + // HACK(eddyb) this accounts for `generic_delimiters` + // printing `::<` instead of `<` if `in_value` is set. + if !printer.empty && !printer.in_value { write!(printer, "::")?; } @@ -1153,10 +1135,9 @@ impl Printer for FmtPrinter { ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, - ns: Namespace, projections: impl Iterator>, ) -> Result { - self.pretty_path_generic_args(print_prefix, params, substs, ns, projections) + self.pretty_path_generic_args(print_prefix, params, substs, projections) } } @@ -1179,6 +1160,36 @@ impl PrettyPrinter for FmtPrinter { }) } + fn print_value_path( + mut self: PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ) -> Result { + let was_in_value = std::mem::replace(&mut self.printer.in_value, true); + let mut printer = self.print_def_path(def_id, substs, iter::empty())?; + printer.in_value = was_in_value; + + Ok(printer) + } + + fn generic_delimiters<'gcx, 'tcx>( + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result { + if !self.printer.empty && self.printer.in_value { + write!(self.printer, "::<")?; + } else { + write!(self.printer, "<")?; + } + + let was_in_value = std::mem::replace(&mut self.printer.in_value, false); + let mut printer = f(self)?; + printer.in_value = was_in_value; + + write!(printer, ">")?; + Ok(printer) + } + fn always_print_region_in_paths( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index f42865f55ec84..204a9574a64f0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -17,7 +17,7 @@ use crate::hir; macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?; Ok(()) }) @@ -262,9 +262,9 @@ pub fn parameterized( substs: SubstsRef<'_>, ns: Namespace, ) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { + PrintCx::with_tls_tcx(FmtPrinter::new(f, ns), |cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.print_def_path(did, Some(substs), ns, iter::empty())?; + cx.print_def_path(did, Some(substs), iter::empty())?; Ok(()) }) } @@ -284,12 +284,7 @@ define_print! { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(|cx| cx.print_def_path( - principal.def_id, - None, - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); nest!(|cx| cx.fn_sig(args, false, proj.ty)); resugared_principal = true; } @@ -303,7 +298,6 @@ define_print! { nest!(|cx| cx.print_def_path( principal.def_id, Some(principal.substs), - Namespace::TypeNS, self.projection_bounds(), )); } @@ -332,12 +326,7 @@ define_print! { } first = false; - nest!(|cx| cx.print_def_path( - def_id, - None, - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); } } } @@ -360,13 +349,8 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { - cx.print_def_path( - self.def_id, - None, - Namespace::TypeNS, - iter::empty(), - )?; + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.print_def_path(self.def_id, None, iter::empty())?; Ok(()) }) } @@ -374,13 +358,8 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| { - cx.print_def_path( - self.did, - None, - Namespace::TypeNS, - iter::empty(), - )?; + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.print_def_path(self.did, None, iter::empty())?; Ok(()) }) } @@ -396,7 +375,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f), |mut cx| { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |mut cx| { define_scoped_cx!(cx); p!(write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, @@ -671,15 +650,10 @@ define_print_multi! { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, cx) { display { - nest!(|cx| cx.print_def_path( - self.def_id, - Some(self.substs), - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); } debug { - nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS)); + nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self))); } } } @@ -730,12 +704,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ty::FnDef(def_id, substs) => { let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); p!(print(sig), write(" {{")); - nest!(|cx| cx.print_def_path( - def_id, - Some(substs), - Namespace::ValueNS, - iter::empty(), - )); + nest!(|cx| cx.print_value_path(def_id, Some(substs))); p!(write("}}")) } ty::FnPtr(ref bare_fn) => { @@ -758,12 +727,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Adt(def, substs) => { - nest!(|cx| cx.print_def_path( - def.did, - Some(substs), - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); } ty::Dynamic(data, r) => { let print_r = self.print_region_outputs_anything(r); @@ -776,12 +740,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(|cx| cx.print_def_path( - def_id, - None, - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -1074,12 +1033,7 @@ define_print! { define_print! { ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { display { - nest!(|cx| cx.print_def_path( - self.item_def_id, - Some(self.substs), - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); } } } @@ -1108,32 +1062,17 @@ define_print! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(|cx| cx.print_def_path( - trait_def_id, - None, - Namespace::TypeNS, - iter::empty(), - )); + nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty())); p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `")); - nest!(|cx| cx.print_def_path( - closure_def_id, - None, - Namespace::ValueNS, - iter::empty(), - )); + nest!(|cx| cx.print_value_path(closure_def_id, None)); p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `")); - nest!(|cx| cx.print_def_path( - def_id, - Some(substs), - Namespace::ValueNS, - iter::empty(), - )); + nest!(|cx| cx.print_value_path(def_id, Some(substs))); p!(write("` can be evaluated")) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 40dc22309664a..3c8bd0dd01b47 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -87,7 +87,6 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. -use rustc::hir::def::Namespace; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; @@ -226,7 +225,7 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { PrintCx::with(tcx, SymbolPath::new(tcx), |cx| { - cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty()) + cx.print_def_path(def_id, None, iter::empty()) .unwrap() .into_interned() }) @@ -437,9 +436,8 @@ impl Printer for SymbolPath { self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, - ns: Namespace, ) -> Result { - self.pretty_path_qualified(self_ty, trait_ref, ns) + self.pretty_path_qualified(self_ty, trait_ref) } fn path_append_impl<'gcx, 'tcx>( @@ -482,10 +480,9 @@ impl Printer for SymbolPath { ) -> Result, params: &[ty::GenericParamDef], substs: SubstsRef<'tcx>, - ns: Namespace, projections: impl Iterator>, ) -> Result { - self.pretty_path_generic_args(print_prefix, params, substs, ns, projections) + self.pretty_path_generic_args(print_prefix, params, substs, projections) } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 9a80415827e89..7a92a507ec160 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -3,6 +3,7 @@ use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource}; use crate::borrow_check::prefixes::IsPrefixOf; use crate::borrow_check::WriteKind; use rustc::hir; +use rustc::hir::def::Namespace; use rustc::hir::def_id::DefId; use rustc::middle::region::ScopeTree; use rustc::mir::{ @@ -2325,7 +2326,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// name where required. fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s); + let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); // We need to add synthesized lifetimes where appropriate. We do // this by hooking into the pretty printer and telling it to label the @@ -2350,7 +2351,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// synthesized lifetime name where required. fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s); + let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); let region = match ty.sty { ty::TyKind::Ref(region, _, _) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 13db78cc803aa..02b8291369d9d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -18,7 +18,7 @@ use rustc::middle::lang_items; use rustc::middle::stability; use rustc::mir::interpret::GlobalId; use rustc::hir::{self, GenericArg, HirVec}; -use rustc::hir::def::{self, Def, CtorKind, Namespace}; +use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; @@ -4260,7 +4260,6 @@ where F: Fn(DefId) -> Def { self: PrintCx<'_, '_, 'tcx, Self>, self_ty: Ty<'tcx>, trait_ref: Option>, - _ns: Namespace, ) -> Result { // This shouldn't ever be needed, but just in case: Ok(vec![match trait_ref { @@ -4307,7 +4306,6 @@ where F: Fn(DefId) -> Def { ) -> Result, _params: &[ty::GenericParamDef], _substs: SubstsRef<'tcx>, - _ns: Namespace, _projections: impl Iterator>, ) -> Result { print_prefix(self) @@ -4315,7 +4313,7 @@ where F: Fn(DefId) -> Def { } let names = PrintCx::with(tcx, AbsolutePathPrinter, |cx| { - cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()).unwrap() + cx.print_def_path(def_id, None, iter::empty()).unwrap() }); hir::Path { From 6d67d6846c9d25b1cffdafd8c330e6374532b5d8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 15 Jan 2019 00:41:14 +0200 Subject: [PATCH 128/157] rustc_codegen_utils: print all nominal types as paths, in symbol names. --- src/librustc_codegen_utils/symbol_names.rs | 30 ++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 3c8bd0dd01b47..a17a554480eb8 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -422,7 +422,18 @@ impl Printer for SymbolPath { self: PrintCx<'_, '_, 'tcx, Self>, ty: Ty<'tcx>, ) -> Result { - self.pretty_print_type(ty) + match ty.sty { + // Print all nominal types as paths (unlike `pretty_print_type`). + ty::FnDef(def_id, substs) | + ty::Opaque(def_id, substs) | + ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) | + ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | + ty::Closure(def_id, ty::ClosureSubsts { substs }) | + ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { + self.print_def_path(def_id, Some(substs), iter::empty()) + } + _ => self.pretty_print_type(ty), + } } fn path_crate( @@ -437,7 +448,22 @@ impl Printer for SymbolPath { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self.pretty_path_qualified(self_ty, trait_ref) + // Similar to `pretty_path_qualified`, but for the other + // types that are printed as paths (see `print_type` above). + match self_ty.sty { + ty::FnDef(..) | + ty::Opaque(..) | + ty::Projection(_) | + ty::UnnormalizedProjection(_) | + ty::Closure(..) | + ty::Generator(..) + if trait_ref.is_none() => + { + self.print_type(self_ty) + } + + _ => self.pretty_path_qualified(self_ty, trait_ref) + } } fn path_append_impl<'gcx, 'tcx>( From 26f180705a993816dd6e16dd7f19775e4325c709 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Jan 2019 19:18:47 +0200 Subject: [PATCH 129/157] rustc: move ty/print.rs to ty/print/mod.rs. --- src/librustc/ty/{print.rs => print/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/librustc/ty/{print.rs => print/mod.rs} (100%) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print/mod.rs similarity index 100% rename from src/librustc/ty/print.rs rename to src/librustc/ty/print/mod.rs From 55871aad9a9c621e245c2b238f04f9fab55da759 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Jan 2019 21:33:31 +0200 Subject: [PATCH 130/157] rustc: split out the pretty-printing parts of ty::print into a separate module. --- src/librustc/mir/mod.rs | 4 +- src/librustc/ty/print/mod.rs | 904 +-------------------- src/librustc/ty/print/pretty.rs | 1305 +++++++++++++++++++++++++++++++ src/librustc/util/ppaux.rs | 386 +-------- 4 files changed, 1324 insertions(+), 1275 deletions(-) create mode 100644 src/librustc/ty/print/pretty.rs diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c2cafac2d5580..0165bba5ed7e3 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2370,7 +2370,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { // When printing regions, add trailing space if necessary. let ns = Namespace::ValueNS; - ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt, ns), |cx| { + ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt, ns), |mut cx| { let region = if cx.config.is_verbose || cx.config.identify_regions { let mut region = region.to_string(); if region.len() > 0 { @@ -2381,7 +2381,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { // Do not even print 'static String::new() }; - write!(cx.printer.fmt, "&{}{}{:?}", region, kind_str, place) + write!(cx.printer, "&{}{}{:?}", region, kind_str, place) }) } diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index a94ae0123d85d..9d93d1a34a13a 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,144 +1,21 @@ -use crate::hir::def::Namespace; use crate::hir::map::DefPathData; -use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use crate::middle::region; +use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; -use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; -use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use syntax::symbol::{keywords, Symbol}; +use crate::ty::subst::{Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; use syntax::symbol::InternedString; -use std::cell::Cell; -use std::fmt::{self, Write as _}; use std::iter; use std::ops::Deref; -thread_local! { - static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); - static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); -} - -/// Force us to name impls with just the filename/line number. We -/// normally try to use types. But at some points, notably while printing -/// cycle errors, this can result in extra or suboptimal error output, -/// so this variable disables that check. -pub fn with_forced_impl_filename_line R, R>(f: F) -> R { - FORCE_IMPL_FILENAME_LINE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - -/// Adds the `crate::` prefix to paths where appropriate. -pub fn with_crate_prefix R, R>(f: F) -> R { - SHOULD_PREFIX_WITH_CRATE.with(|flag| { - let old = flag.get(); - flag.set(true); - let result = f(); - flag.set(old); - result - }) -} +// `pretty` is a separate module only for organization. +mod pretty; +pub use self::pretty::*; // FIXME(eddyb) this module uses `pub(crate)` for things used only // from `ppaux` - when that is removed, they can be re-privatized. -/// The "region highlights" are used to control region printing during -/// specific error messages. When a "region highlight" is enabled, it -/// gives an alternate way to print specific regions. For now, we -/// always print those regions using a number, so something like "`'0`". -/// -/// Regions not selected by the region highlight mode are presently -/// unaffected. -#[derive(Copy, Clone, Default)] -pub struct RegionHighlightMode { - /// If enabled, when we see the selected region, use "`'N`" - /// instead of the ordinary behavior. - highlight_regions: [Option<(ty::RegionKind, usize)>; 3], - - /// If enabled, when printing a "free region" that originated from - /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily - /// have names print as normal. - /// - /// This is used when you have a signature like `fn foo(x: &u32, - /// y: &'a u32)` and we want to give a name to the region of the - /// reference `x`. - highlight_bound_region: Option<(ty::BoundRegion, usize)>, -} - -impl RegionHighlightMode { - /// If `region` and `number` are both `Some`, invokes - /// `highlighting_region`. - pub fn maybe_highlighting_region( - &mut self, - region: Option>, - number: Option, - ) { - if let Some(k) = region { - if let Some(n) = number { - self.highlighting_region(k, n); - } - } - } - - /// Highlights the region inference variable `vid` as `'N`. - pub fn highlighting_region( - &mut self, - region: ty::Region<'_>, - number: usize, - ) { - let num_slots = self.highlight_regions.len(); - let first_avail_slot = self.highlight_regions.iter_mut() - .filter(|s| s.is_none()) - .next() - .unwrap_or_else(|| { - bug!( - "can only highlight {} placeholders at a time", - num_slots, - ) - }); - *first_avail_slot = Some((*region, number)); - } - - /// Convenience wrapper for `highlighting_region`. - pub fn highlighting_region_vid( - &mut self, - vid: ty::RegionVid, - number: usize, - ) { - self.highlighting_region(&ty::ReVar(vid), number) - } - - /// Returns `Some(n)` with the number to use for the given region, if any. - fn region_highlighted(&self, region: ty::Region<'_>) -> Option { - self - .highlight_regions - .iter() - .filter_map(|h| match h { - Some((r, n)) if r == region => Some(*n), - _ => None, - }) - .next() - } - - /// Highlight the given bound region. - /// We can only highlight one bound region at a time. See - /// the field `highlight_bound_region` for more detailed notes. - pub fn highlighting_bound_region( - &mut self, - br: ty::BoundRegion, - number: usize, - ) { - assert!(self.highlight_bound_region.is_none()); - self.highlight_bound_region = Some((br, number)); - } -} - struct LateBoundRegionNameCollector(FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { @@ -156,13 +33,13 @@ pub(crate) struct PrintConfig { pub(crate) is_debug: bool, pub(crate) is_verbose: bool, pub(crate) identify_regions: bool, - pub(crate) used_region_names: Option>, - pub(crate) region_index: usize, - pub(crate) binder_depth: usize, + used_region_names: Option>, + region_index: usize, + binder_depth: usize, } impl PrintConfig { - pub(crate) fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { + fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { PrintConfig { is_debug: false, is_verbose: tcx.sess.verbose(), @@ -205,7 +82,7 @@ impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { pub(crate) fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { ty::tls::with(|tcx| PrintCx::with(tcx, printer, f)) } - pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) + fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx> { let mut collector = LateBoundRegionNameCollector(Default::default()); @@ -318,109 +195,6 @@ pub trait Printer: Sized { ) -> Result; } -/// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: - Printer< - Error = fmt::Error, - Path = Self, - Region = Self, - Type = Self, - > + - fmt::Write -{ - /// Enter a nested print context, for pretty-printing - /// nested components in some larger context. - fn nest<'a, 'gcx, 'tcx, E>( - self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result, E> { - let printer = f(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - })?; - Ok(PrintCx { - tcx: self.tcx, - printer, - config: self.config, - }) - } - - /// Like `print_def_path` but for value paths. - fn print_value_path( - self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { - self.print_def_path(def_id, substs, iter::empty()) - } - - /// Print `<...>` around what `f` prints. - fn generic_delimiters<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result; - - /// Return `true` if the region should be printed in path generic args - /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. - fn always_print_region_in_paths( - self: &PrintCx<'_, '_, '_, Self>, - _region: ty::Region<'_>, - ) -> bool { - false - } - - // HACK(eddyb) Trying to print a lifetime might not print anything, which - // may need special handling in the caller (of `ty::RegionKind::print`). - // To avoid printing to a temporary string (which isn't even supported), - // the `print_region_outputs_anything` method can instead be used to - // determine this, ahead of time. - // - // NB: this must be kept in sync with the implementation of `print_region`. - fn print_region_outputs_anything( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool; -} - -macro_rules! nest { - ($cx:ident, $closure:expr) => { - $cx = $cx.nest($closure)? - } -} - -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always - // (but also some things just print a `DefId` generally so maybe we need this?) - fn guess_def_namespace(self, def_id: DefId) -> Namespace { - match self.def_key(def_id).disambiguated_data.data { - DefPathData::ValueNs(..) | - DefPathData::EnumVariant(..) | - DefPathData::Field(..) | - DefPathData::AnonConst | - DefPathData::ConstParam(..) | - DefPathData::ClosureExpr | - DefPathData::StructCtor => Namespace::ValueNS, - - DefPathData::MacroDef(..) => Namespace::MacroNS, - - _ => Namespace::TypeNS, - } - } - - /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { - let ns = self.guess_def_namespace(def_id); - debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); - let mut s = String::new(); - let _ = PrintCx::with(self, FmtPrinter::new(&mut s, ns), |cx| { - cx.print_def_path(def_id, None, iter::empty()) - }); - s - } -} - impl PrintCx<'a, 'gcx, 'tcx, P> { pub fn default_print_def_path( self, @@ -588,661 +362,3 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { ty::Float(_) => None, } } - -pub struct FmtPrinter { - pub(crate) fmt: F, - empty: bool, - in_value: bool, - pub region_highlight_mode: RegionHighlightMode, -} - -impl FmtPrinter { - pub fn new(fmt: F, ns: Namespace) -> Self { - FmtPrinter { - fmt, - empty: true, - in_value: ns == Namespace::ValueNS, - region_highlight_mode: RegionHighlightMode::default(), - } - } -} - -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { - /// If possible, this returns a global path resolving to `def_id` that is visible - /// from at least one local module and returns true. If the crate defining `def_id` is - /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path( - mut self, - def_id: DefId, - ) -> Result<(P, bool), P::Error> { - debug!("try_print_visible_def_path: def_id={:?}", def_id); - - // If `def_id` is a direct or injected extern crate, return the - // path to the crate followed by the path to the item within the crate. - if def_id.index == CRATE_DEF_INDEX { - let cnum = def_id.krate; - - if cnum == LOCAL_CRATE { - return Ok((self.path_crate(cnum)?, true)); - } - - // In local mode, when we encounter a crate other than - // LOCAL_CRATE, execution proceeds in one of two ways: - // - // 1. for a direct dependency, where user added an - // `extern crate` manually, we put the `extern - // crate` as the parent. So you wind up with - // something relative to the current crate. - // 2. for an extern inferred from a path or an indirect crate, - // where there is no explicit `extern crate`, we just prepend - // the crate name. - match *self.tcx.extern_crate(def_id) { - Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - span, - .. - }) => { - debug!("try_print_visible_def_path: def_id={:?}", def_id); - return Ok((if !span.is_dummy() { - self.print_def_path(def_id, None, iter::empty())? - } else { - self.path_crate(cnum)? - }, true)); - } - None => { - return Ok((self.path_crate(cnum)?, true)); - } - _ => {}, - } - } - - if def_id.is_local() { - return Ok((self.printer, false)); - } - - let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); - - let mut cur_def_key = self.tcx.def_key(def_id); - debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); - - // For a UnitStruct or TupleStruct we want the name of its parent rather than . - if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { - let parent = DefId { - krate: def_id.krate, - index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), - }; - - cur_def_key = self.tcx.def_key(parent); - } - - let visible_parent = match visible_parent_map.get(&def_id).cloned() { - Some(parent) => parent, - None => return Ok((self.printer, false)), - }; - // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether - // the entire path will succeed or not. To support printers that do not - // implement `PrettyPrinter`, a `Vec` or linked list on the stack would - // need to be built, before starting to print anything. - let mut prefix_success = false; - nest!(self, |cx| { - let (printer, success) = cx.try_print_visible_def_path(visible_parent)?; - prefix_success = success; - Ok(printer) - }); - if !prefix_success { - return Ok((self.printer, false)); - }; - let actual_parent = self.tcx.parent(def_id); - - let data = cur_def_key.disambiguated_data.data; - debug!( - "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", - data, visible_parent, actual_parent, - ); - - let symbol = match data { - // In order to output a path that could actually be imported (valid and visible), - // we need to handle re-exports correctly. - // - // For example, take `std::os::unix::process::CommandExt`, this trait is actually - // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). - // - // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is - // private so the "true" path to `CommandExt` isn't accessible. - // - // In this case, the `visible_parent_map` will look something like this: - // - // (child) -> (parent) - // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` - // `std::sys::unix::ext::process` -> `std::sys::unix::ext` - // `std::sys::unix::ext` -> `std::os` - // - // This is correct, as the visible parent of `std::sys::unix::ext` is in fact - // `std::os`. - // - // When printing the path to `CommandExt` and looking at the `cur_def_key` that - // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go - // to the parent - resulting in a mangled path like - // `std::os::ext::process::CommandExt`. - // - // Instead, we must detect that there was a re-export and instead print `unix` - // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To - // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with - // the visible parent (`std::os`). If these do not match, then we iterate over - // the children of the visible parent (as was done when computing - // `visible_parent_map`), looking for the specific child we currently have and then - // have access to the re-exported name. - DefPathData::Module(actual_name) | - DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - self.tcx.item_children(visible_parent) - .iter() - .find(|child| child.def.def_id() == def_id) - .map(|child| child.ident.as_str()) - .unwrap_or_else(|| actual_name.as_str()) - } - _ => { - data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { - // Re-exported `extern crate` (#43189). - if let DefPathData::CrateRoot = data { - self.tcx.original_crate_name(def_id.krate).as_str() - } else { - Symbol::intern("").as_str() - } - }) - }, - }; - debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok((self.path_append(|cx| Ok(cx.printer), &symbol)?, true)) - } - - pub fn pretty_path_qualified( - self, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - if trait_ref.is_none() { - // Inherent impls. Try to print `Foo::bar` for an inherent - // impl on `Foo`, but fallback to `::bar` if self-type is - // anything other than a simple path. - match self_ty.sty { - ty::Adt(..) | ty::Foreign(_) | - ty::Bool | ty::Char | ty::Str | - ty::Int(_) | ty::Uint(_) | ty::Float(_) => { - return self_ty.print_display(self); - } - - _ => {} - } - } - - self.generic_delimiters(|mut cx| { - nest!(cx, |cx| self_ty.print_display(cx)); - if let Some(trait_ref) = trait_ref { - write!(cx.printer, " as ")?; - nest!(cx, |cx| trait_ref.print_display(cx)); - } - Ok(cx.printer) - }) - } - - pub fn pretty_path_append_impl( - mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - nest!(self, print_prefix); - - self.generic_delimiters(|mut cx| { - write!(cx.printer, "impl ")?; - if let Some(trait_ref) = trait_ref { - nest!(cx, |cx| trait_ref.print_display(cx)); - write!(cx.printer, " for ")?; - } - nest!(cx, |cx| self_ty.print_display(cx)); - - Ok(cx.printer) - }) - } - - pub fn pretty_path_generic_args( - mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, - projections: impl Iterator>, - ) -> Result { - nest!(self, |cx| print_prefix(cx)); - - // Don't print `'_` if there's no printed region. - let print_regions = params.iter().any(|param| { - match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(r) => { - self.always_print_region_in_paths(r) || - self.print_region_outputs_anything(r) - } - _ => false, - } - }); - - // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = if self.config.is_verbose { - 0 - } else { - params.iter().rev().take_while(|param| { - match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default && substs[param.index as usize] == Kind::from( - self.tcx.type_of(param.def_id).subst(self.tcx, substs) - ) - } - ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) - } - }).count() - }; - - let params = ¶ms[..params.len() - num_supplied_defaults]; - let mut args = params.iter().map(|param| { - substs[param.index as usize].unpack() - }).filter(|arg| { - match arg { - UnpackedKind::Lifetime(_) => print_regions, - _ => true, - } - }); - let arg0 = args.next(); - - let mut projections = projections; - let projection0 = projections.next(); - - if arg0.is_none() && projection0.is_none() { - return Ok(self.printer); - } - - self.generic_delimiters(|mut cx| { - let mut empty = true; - let mut maybe_comma = |cx: &mut Self| { - if empty { - empty = false; - Ok(()) - } else { - write!(cx.printer, ", ") - } - }; - - for arg in arg0.into_iter().chain(args) { - maybe_comma(&mut cx)?; - - match arg { - UnpackedKind::Lifetime(region) => { - if !cx.print_region_outputs_anything(region) { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(cx.printer, "'_")?; - } else { - nest!(cx, |cx| region.print_display(cx)); - } - } - UnpackedKind::Type(ty) => { - nest!(cx, |cx| ty.print_display(cx)); - } - UnpackedKind::Const(ct) => { - nest!(cx, |cx| ct.print_display(cx)); - } - } - } - - for projection in projection0.into_iter().chain(projections) { - maybe_comma(&mut cx)?; - - write!(cx.printer, "{}=", - cx.tcx.associated_item(projection.item_def_id).ident)?; - nest!(cx, |cx| projection.ty.print_display(cx)); - } - - Ok(cx.printer) - }) - } -} - -impl fmt::Write for FmtPrinter { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.empty &= s.is_empty(); - self.fmt.write_str(s) - } -} - -impl Printer for FmtPrinter { - type Error = fmt::Error; - - type Path = Self; - type Region = Self; - type Type = Self; - - fn print_def_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - projections: impl Iterator>, - ) -> Result { - // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` - // both here and in `default_print_def_path`. - let generics = substs.map(|_| self.tcx.generics_of(def_id)); - if generics.as_ref().and_then(|g| g.parent).is_none() { - let mut visible_path_success = false; - nest!(self, |cx| { - let (printer, success) = cx.try_print_visible_def_path(def_id)?; - visible_path_success = success; - Ok(printer) - }); - if visible_path_success { - return if let (Some(generics), Some(substs)) = (generics, substs) { - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(|cx| Ok(cx.printer), params, substs, projections) - } else { - Ok(self.printer) - }; - } - } - - let key = self.tcx.def_key(def_id); - if let DefPathData::Impl = key.disambiguated_data.data { - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = - !def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let span = self.tcx.def_span(def_id); - return self.path_append( - |cx| cx.print_def_path(parent_def_id, None, iter::empty()), - &format!("", span), - ); - } - } - - self.default_print_def_path(def_id, substs, projections) - } - - fn print_region( - mut self: PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> Result { - // Watch out for region highlights. - let highlight = self.printer.region_highlight_mode; - if let Some(n) = highlight.region_highlighted(region) { - write!(self.printer, "'{}", n)?; - return Ok(self.printer); - } - - if self.config.is_verbose { - return region.print_debug(self); - } - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *region { - ty::ReEarlyBound(ref data) => { - if data.name != "'_" { - write!(self.printer, "{}", data.name)?; - } - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - write!(self.printer, "{}", name)?; - return Ok(self.printer); - } - } - - if let Some((region, counter)) = highlight.highlight_bound_region { - if br == region { - write!(self.printer, "'{}", counter)?; - } - } - } - ty::ReScope(scope) if self.config.identify_regions => { - match scope.data { - region::ScopeData::Node => - write!(self.printer, "'{}s", scope.item_local_id().as_usize())?, - region::ScopeData::CallSite => - write!(self.printer, "'{}cs", scope.item_local_id().as_usize())?, - region::ScopeData::Arguments => - write!(self.printer, "'{}as", scope.item_local_id().as_usize())?, - region::ScopeData::Destruction => - write!(self.printer, "'{}ds", scope.item_local_id().as_usize())?, - region::ScopeData::Remainder(first_statement_index) => write!(self.printer, - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - )?, - } - } - ty::ReVar(region_vid) if self.config.identify_regions => { - write!(self.printer, "{:?}", region_vid)?; - } - ty::ReVar(_) => {} - ty::ReScope(_) | - ty::ReErased => {} - ty::ReStatic => write!(self.printer, "'static")?, - ty::ReEmpty => write!(self.printer, "'")?, - - // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => write!(self.printer, "{:?}", vid)?, - } - - Ok(self.printer) - } - - fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, - ty: Ty<'tcx>, - ) -> Result { - self.pretty_print_type(ty) - } - - fn path_crate( - mut self: PrintCx<'_, '_, '_, Self>, - cnum: CrateNum, - ) -> Result { - if cnum == LOCAL_CRATE { - if self.tcx.sess.rust_2018() { - // We add the `crate::` keyword on Rust 2018, only when desired. - if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - write!(self.printer, "{}", keywords::Crate.name())?; - } - } - Ok(self.printer) - } else { - write!(self.printer, "{}", self.tcx.crate_name(cnum))?; - Ok(self.printer) - } - } - fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - self.pretty_path_qualified(self_ty, trait_ref) - } - - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - self.pretty_path_append_impl(|cx| { - let mut printer = print_prefix(cx)?; - - // HACK(eddyb) this accounts for `generic_delimiters` - // printing `::<` instead of `<` if `in_value` is set. - if !printer.empty && !printer.in_value { - write!(printer, "::")?; - } - - Ok(printer) - }, self_ty, trait_ref) - } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - text: &str, - ) -> Result { - let mut printer = print_prefix(self)?; - - // FIXME(eddyb) `text` should never be empty, but it - // currently is for `extern { ... }` "foreign modules". - if !text.is_empty() { - if !printer.empty { - write!(printer, "::")?; - } - write!(printer, "{}", text)?; - } - - Ok(printer) - } - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, - projections: impl Iterator>, - ) -> Result { - self.pretty_path_generic_args(print_prefix, params, substs, projections) - } -} - -impl PrettyPrinter for FmtPrinter { - fn nest<'a, 'gcx, 'tcx, E>( - mut self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result, E> { - let was_empty = std::mem::replace(&mut self.printer.empty, true); - let mut printer = f(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - })?; - printer.empty &= was_empty; - Ok(PrintCx { - tcx: self.tcx, - printer, - config: self.config, - }) - } - - fn print_value_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { - let was_in_value = std::mem::replace(&mut self.printer.in_value, true); - let mut printer = self.print_def_path(def_id, substs, iter::empty())?; - printer.in_value = was_in_value; - - Ok(printer) - } - - fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result { - if !self.printer.empty && self.printer.in_value { - write!(self.printer, "::<")?; - } else { - write!(self.printer, "<")?; - } - - let was_in_value = std::mem::replace(&mut self.printer.in_value, false); - let mut printer = f(self)?; - printer.in_value = was_in_value; - - write!(printer, ">")?; - Ok(printer) - } - - fn always_print_region_in_paths( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool { - *region != ty::ReErased - } - - fn print_region_outputs_anything( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool { - let highlight = self.printer.region_highlight_mode; - if highlight.region_highlighted(region).is_some() { - return true; - } - - if self.config.is_verbose { - return true; - } - - match *region { - ty::ReEarlyBound(ref data) => { - data.name != "" && data.name != "'_" - } - - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - return true; - } - } - - if let Some((region, _)) = highlight.highlight_bound_region { - if br == region { - return true; - } - } - - false - } - - ty::ReScope(_) | - ty::ReVar(_) if self.config.identify_regions => true, - - ty::ReVar(_) | - ty::ReScope(_) | - ty::ReErased => false, - - ty::ReStatic | - ty::ReEmpty | - ty::ReClosureBound(_) => true, - } - } -} diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs new file mode 100644 index 0000000000000..caa4090625d91 --- /dev/null +++ b/src/librustc/ty/print/pretty.rs @@ -0,0 +1,1305 @@ +use crate::hir; +use crate::hir::def::Namespace; +use crate::hir::map::DefPathData; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::middle::cstore::{ExternCrate, ExternCrateSource}; +use crate::middle::region; +use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; +use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; +use crate::mir::interpret::ConstValue; +use syntax::symbol::{keywords, Symbol}; + +use syntax::symbol::InternedString; + +use std::cell::Cell; +use std::fmt::{self, Write as _}; +use std::iter; + +// `pretty` is a separate module only for organization. +use super::*; + +macro_rules! nest { + ($closure:expr) => { + scoped_cx!() = scoped_cx!().nest($closure)? + } +} +macro_rules! print_inner { + (write ($($data:expr),+)) => { + write!(scoped_cx!().printer, $($data),+)? + }; + ($kind:ident ($data:expr)) => { + nest!(|cx| $data.$kind(cx)) + }; +} +macro_rules! p { + ($($kind:ident $data:tt),+) => { + { + $(print_inner!($kind $data));+ + } + }; +} +macro_rules! define_scoped_cx { + ($cx:ident) => { + #[allow(unused_macros)] + macro_rules! scoped_cx { + () => ($cx) + } + }; +} + +thread_local! { + static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); + static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); +} + +/// Force us to name impls with just the filename/line number. We +/// normally try to use types. But at some points, notably while printing +/// cycle errors, this can result in extra or suboptimal error output, +/// so this variable disables that check. +pub fn with_forced_impl_filename_line R, R>(f: F) -> R { + FORCE_IMPL_FILENAME_LINE.with(|force| { + let old = force.get(); + force.set(true); + let result = f(); + force.set(old); + result + }) +} + +/// Adds the `crate::` prefix to paths where appropriate. +pub fn with_crate_prefix R, R>(f: F) -> R { + SHOULD_PREFIX_WITH_CRATE.with(|flag| { + let old = flag.get(); + flag.set(true); + let result = f(); + flag.set(old); + result + }) +} + +/// The "region highlights" are used to control region printing during +/// specific error messages. When a "region highlight" is enabled, it +/// gives an alternate way to print specific regions. For now, we +/// always print those regions using a number, so something like "`'0`". +/// +/// Regions not selected by the region highlight mode are presently +/// unaffected. +#[derive(Copy, Clone, Default)] +pub struct RegionHighlightMode { + /// If enabled, when we see the selected region, use "`'N`" + /// instead of the ordinary behavior. + highlight_regions: [Option<(ty::RegionKind, usize)>; 3], + + /// If enabled, when printing a "free region" that originated from + /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily + /// have names print as normal. + /// + /// This is used when you have a signature like `fn foo(x: &u32, + /// y: &'a u32)` and we want to give a name to the region of the + /// reference `x`. + highlight_bound_region: Option<(ty::BoundRegion, usize)>, +} + +impl RegionHighlightMode { + /// If `region` and `number` are both `Some`, invokes + /// `highlighting_region`. + pub fn maybe_highlighting_region( + &mut self, + region: Option>, + number: Option, + ) { + if let Some(k) = region { + if let Some(n) = number { + self.highlighting_region(k, n); + } + } + } + + /// Highlights the region inference variable `vid` as `'N`. + pub fn highlighting_region( + &mut self, + region: ty::Region<'_>, + number: usize, + ) { + let num_slots = self.highlight_regions.len(); + let first_avail_slot = self.highlight_regions.iter_mut() + .filter(|s| s.is_none()) + .next() + .unwrap_or_else(|| { + bug!( + "can only highlight {} placeholders at a time", + num_slots, + ) + }); + *first_avail_slot = Some((*region, number)); + } + + /// Convenience wrapper for `highlighting_region`. + pub fn highlighting_region_vid( + &mut self, + vid: ty::RegionVid, + number: usize, + ) { + self.highlighting_region(&ty::ReVar(vid), number) + } + + /// Returns `Some(n)` with the number to use for the given region, if any. + fn region_highlighted(&self, region: ty::Region<'_>) -> Option { + self + .highlight_regions + .iter() + .filter_map(|h| match h { + Some((r, n)) if r == region => Some(*n), + _ => None, + }) + .next() + } + + /// Highlight the given bound region. + /// We can only highlight one bound region at a time. See + /// the field `highlight_bound_region` for more detailed notes. + pub fn highlighting_bound_region( + &mut self, + br: ty::BoundRegion, + number: usize, + ) { + assert!(self.highlight_bound_region.is_none()); + self.highlight_bound_region = Some((br, number)); + } +} + +/// Trait for printers that pretty-print using `fmt::Write` to the printer. +pub trait PrettyPrinter: + Printer< + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + > + + fmt::Write +{ + /// Enter a nested print context, for pretty-printing + /// nested components in some larger context. + fn nest<'a, 'gcx, 'tcx, E>( + self: PrintCx<'a, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result, E> { + let printer = f(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + })?; + Ok(PrintCx { + tcx: self.tcx, + printer, + config: self.config, + }) + } + + /// Like `print_def_path` but for value paths. + fn print_value_path( + self: PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ) -> Result { + self.print_def_path(def_id, substs, iter::empty()) + } + + /// Print `<...>` around what `f` prints. + fn generic_delimiters<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result; + + /// Return `true` if the region should be printed in path generic args + /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. + fn always_print_region_in_paths( + self: &PrintCx<'_, '_, '_, Self>, + _region: ty::Region<'_>, + ) -> bool { + false + } + + // HACK(eddyb) Trying to print a lifetime might not print anything, which + // may need special handling in the caller (of `ty::RegionKind::print`). + // To avoid printing to a temporary string (which isn't even supported), + // the `print_region_outputs_anything` method can instead be used to + // determine this, ahead of time. + // + // NB: this must be kept in sync with the implementation of `print_region`. + fn print_region_outputs_anything( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool; +} + +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ConstParam(..) | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + + /// Returns a string identifying this `DefId. This string is + /// suitable for user output. + pub fn def_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); + let mut s = String::new(); + let _ = PrintCx::with(self, FmtPrinter::new(&mut s, ns), |cx| { + cx.print_def_path(def_id, None, iter::empty()) + }); + s + } +} + +pub struct FmtPrinter { + fmt: F, + empty: bool, + in_value: bool, + pub region_highlight_mode: RegionHighlightMode, +} + +impl FmtPrinter { + pub fn new(fmt: F, ns: Namespace) -> Self { + FmtPrinter { + fmt, + empty: true, + in_value: ns == Namespace::ValueNS, + region_highlight_mode: RegionHighlightMode::default(), + } + } +} + +impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { + /// If possible, this returns a global path resolving to `def_id` that is visible + /// from at least one local module and returns true. If the crate defining `def_id` is + /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. + fn try_print_visible_def_path( + mut self, + def_id: DefId, + ) -> Result<(P, bool), P::Error> { + define_scoped_cx!(self); + + debug!("try_print_visible_def_path: def_id={:?}", def_id); + + // If `def_id` is a direct or injected extern crate, return the + // path to the crate followed by the path to the item within the crate. + if def_id.index == CRATE_DEF_INDEX { + let cnum = def_id.krate; + + if cnum == LOCAL_CRATE { + return Ok((self.path_crate(cnum)?, true)); + } + + // In local mode, when we encounter a crate other than + // LOCAL_CRATE, execution proceeds in one of two ways: + // + // 1. for a direct dependency, where user added an + // `extern crate` manually, we put the `extern + // crate` as the parent. So you wind up with + // something relative to the current crate. + // 2. for an extern inferred from a path or an indirect crate, + // where there is no explicit `extern crate`, we just prepend + // the crate name. + match *self.tcx.extern_crate(def_id) { + Some(ExternCrate { + src: ExternCrateSource::Extern(def_id), + direct: true, + span, + .. + }) => { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + return Ok((if !span.is_dummy() { + self.print_def_path(def_id, None, iter::empty())? + } else { + self.path_crate(cnum)? + }, true)); + } + None => { + return Ok((self.path_crate(cnum)?, true)); + } + _ => {}, + } + } + + if def_id.is_local() { + return Ok((self.printer, false)); + } + + let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); + + let mut cur_def_key = self.tcx.def_key(def_id); + debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); + + // For a UnitStruct or TupleStruct we want the name of its parent rather than . + if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { + let parent = DefId { + krate: def_id.krate, + index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), + }; + + cur_def_key = self.tcx.def_key(parent); + } + + let visible_parent = match visible_parent_map.get(&def_id).cloned() { + Some(parent) => parent, + None => return Ok((self.printer, false)), + }; + // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether + // the entire path will succeed or not. To support printers that do not + // implement `PrettyPrinter`, a `Vec` or linked list on the stack would + // need to be built, before starting to print anything. + let mut prefix_success = false; + nest!(|cx| { + let (printer, success) = cx.try_print_visible_def_path(visible_parent)?; + prefix_success = success; + Ok(printer) + }); + if !prefix_success { + return Ok((self.printer, false)); + }; + let actual_parent = self.tcx.parent(def_id); + debug!( + "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", + visible_parent, actual_parent, + ); + + let data = cur_def_key.disambiguated_data.data; + debug!( + "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", + data, visible_parent, actual_parent, + ); + + let symbol = match data { + // In order to output a path that could actually be imported (valid and visible), + // we need to handle re-exports correctly. + // + // For example, take `std::os::unix::process::CommandExt`, this trait is actually + // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). + // + // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is + // private so the "true" path to `CommandExt` isn't accessible. + // + // In this case, the `visible_parent_map` will look something like this: + // + // (child) -> (parent) + // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` + // `std::sys::unix::ext::process` -> `std::sys::unix::ext` + // `std::sys::unix::ext` -> `std::os` + // + // This is correct, as the visible parent of `std::sys::unix::ext` is in fact + // `std::os`. + // + // When printing the path to `CommandExt` and looking at the `cur_def_key` that + // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go + // to the parent - resulting in a mangled path like + // `std::os::ext::process::CommandExt`. + // + // Instead, we must detect that there was a re-export and instead print `unix` + // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To + // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with + // the visible parent (`std::os`). If these do not match, then we iterate over + // the children of the visible parent (as was done when computing + // `visible_parent_map`), looking for the specific child we currently have and then + // have access to the re-exported name. + DefPathData::Module(actual_name) | + DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { + self.tcx.item_children(visible_parent) + .iter() + .find(|child| child.def.def_id() == def_id) + .map(|child| child.ident.as_str()) + .unwrap_or_else(|| actual_name.as_str()) + } + _ => { + data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { + // Re-exported `extern crate` (#43189). + if let DefPathData::CrateRoot = data { + self.tcx.original_crate_name(def_id.krate).as_str() + } else { + Symbol::intern("").as_str() + } + }) + }, + }; + debug!("try_print_visible_def_path: symbol={:?}", symbol); + Ok((self.path_append(|cx| Ok(cx.printer), &symbol)?, true)) + } + + pub fn pretty_path_qualified( + self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + if trait_ref.is_none() { + // Inherent impls. Try to print `Foo::bar` for an inherent + // impl on `Foo`, but fallback to `::bar` if self-type is + // anything other than a simple path. + match self_ty.sty { + ty::Adt(..) | ty::Foreign(_) | + ty::Bool | ty::Char | ty::Str | + ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + return self_ty.print_display(self); + } + + _ => {} + } + } + + self.generic_delimiters(|mut cx| { + define_scoped_cx!(cx); + + p!(print_display(self_ty)); + if let Some(trait_ref) = trait_ref { + p!(write(" as "), print_display(trait_ref)); + } + Ok(cx.printer) + }) + } + + pub fn pretty_path_append_impl( + mut self, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, P>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.nest(print_prefix)?; + + self.generic_delimiters(|mut cx| { + define_scoped_cx!(cx); + + p!(write("impl ")); + if let Some(trait_ref) = trait_ref { + p!(print_display(trait_ref), write(" for ")); + } + p!(print_display(self_ty)); + + Ok(cx.printer) + }) + } + + pub fn pretty_path_generic_args( + mut self, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, P>, + ) -> Result, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + projections: impl Iterator>, + ) -> Result { + self = self.nest(print_prefix)?; + + // Don't print `'_` if there's no printed region. + let print_regions = params.iter().any(|param| { + match substs[param.index as usize].unpack() { + UnpackedKind::Lifetime(r) => { + self.always_print_region_in_paths(r) || + self.print_region_outputs_anything(r) + } + _ => false, + } + }); + + // Don't print args that are the defaults of their respective parameters. + let num_supplied_defaults = if self.config.is_verbose { + 0 + } else { + params.iter().rev().take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default && substs[param.index as usize] == Kind::from( + self.tcx.type_of(param.def_id).subst(self.tcx, substs) + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) + } + }).count() + }; + + let params = ¶ms[..params.len() - num_supplied_defaults]; + let mut args = params.iter().map(|param| { + substs[param.index as usize] + }).filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + let arg0 = args.next(); + + let mut projections = projections; + let projection0 = projections.next(); + + if arg0.is_none() && projection0.is_none() { + return Ok(self.printer); + } + + self.generic_delimiters(|mut cx| { + define_scoped_cx!(cx); + + let mut empty = true; + let mut maybe_comma = |cx: &mut Self| { + if empty { + empty = false; + Ok(()) + } else { + write!(cx.printer, ", ") + } + }; + + for arg in arg0.into_iter().chain(args) { + maybe_comma(&mut cx)?; + + if let UnpackedKind::Lifetime(region) = arg.unpack() { + if !cx.print_region_outputs_anything(region) { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + p!(write("'_")); + + continue; + } + } + + p!(print_display(arg)); + } + + for projection in projection0.into_iter().chain(projections) { + maybe_comma(&mut cx)?; + + p!(write("{}=", cx.tcx.associated_item(projection.item_def_id).ident), + print_display(projection.ty)); + } + + Ok(cx.printer) + }) + } +} + +impl fmt::Write for FmtPrinter { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.empty &= s.is_empty(); + self.fmt.write_str(s) + } +} + +impl Printer for FmtPrinter { + type Error = fmt::Error; + + type Path = Self; + type Region = Self; + type Type = Self; + + fn print_def_path( + mut self: PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + projections: impl Iterator>, + ) -> Result { + // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` + // both here and in `default_print_def_path`. + let generics = substs.map(|_| self.tcx.generics_of(def_id)); + if generics.as_ref().and_then(|g| g.parent).is_none() { + let mut visible_path_success = false; + self = self.nest(|cx| { + let (printer, success) = cx.try_print_visible_def_path(def_id)?; + visible_path_success = success; + Ok(printer) + })?; + if visible_path_success { + return if let (Some(generics), Some(substs)) = (generics, substs) { + let has_own_self = generics.has_self && generics.parent_count == 0; + let params = &generics.params[has_own_self as usize..]; + self.path_generic_args(|cx| Ok(cx.printer), params, substs, projections) + } else { + Ok(self.printer) + }; + } + } + + let key = self.tcx.def_key(def_id); + if let DefPathData::Impl = key.disambiguated_data.data { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = + !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let span = self.tcx.def_span(def_id); + return self.path_append( + |cx| cx.print_def_path(parent_def_id, None, iter::empty()), + &format!("", span), + ); + } + } + + self.default_print_def_path(def_id, substs, projections) + } + + fn print_region( + self: PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> Result { + self.pretty_print_region(region) + } + + fn print_type( + self: PrintCx<'_, '_, 'tcx, Self>, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + + fn path_crate( + mut self: PrintCx<'_, '_, '_, Self>, + cnum: CrateNum, + ) -> Result { + if cnum == LOCAL_CRATE { + if self.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + write!(self.printer, "{}", keywords::Crate.name())?; + } + } + Ok(self.printer) + } else { + write!(self.printer, "{}", self.tcx.crate_name(cnum))?; + Ok(self.printer) + } + } + fn path_qualified( + self: PrintCx<'_, '_, 'tcx, Self>, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self.pretty_path_qualified(self_ty, trait_ref) + } + + fn path_append_impl<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self.pretty_path_append_impl(|cx| { + let mut printer = print_prefix(cx)?; + + // HACK(eddyb) this accounts for `generic_delimiters` + // printing `::<` instead of `<` if `in_value` is set. + if !printer.empty && !printer.in_value { + write!(printer, "::")?; + } + + Ok(printer) + }, self_ty, trait_ref) + } + fn path_append<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + text: &str, + ) -> Result { + let mut printer = print_prefix(self)?; + + // FIXME(eddyb) `text` should never be empty, but it + // currently is for `extern { ... }` "foreign modules". + if !text.is_empty() { + if !printer.empty { + write!(printer, "::")?; + } + write!(printer, "{}", text)?; + } + + Ok(printer) + } + fn path_generic_args<'gcx, 'tcx>( + self: PrintCx<'_, 'gcx, 'tcx, Self>, + print_prefix: impl FnOnce( + PrintCx<'_, 'gcx, 'tcx, Self>, + ) -> Result, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + projections: impl Iterator>, + ) -> Result { + self.pretty_path_generic_args(print_prefix, params, substs, projections) + } +} + +impl PrettyPrinter for FmtPrinter { + fn nest<'a, 'gcx, 'tcx, E>( + mut self: PrintCx<'a, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result, E> { + let was_empty = std::mem::replace(&mut self.printer.empty, true); + let mut printer = f(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + })?; + printer.empty &= was_empty; + Ok(PrintCx { + tcx: self.tcx, + printer, + config: self.config, + }) + } + + fn print_value_path( + mut self: PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ) -> Result { + let was_in_value = std::mem::replace(&mut self.printer.in_value, true); + let mut printer = self.print_def_path(def_id, substs, iter::empty())?; + printer.in_value = was_in_value; + + Ok(printer) + } + + fn generic_delimiters<'gcx, 'tcx>( + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, + f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + ) -> Result { + if !self.printer.empty && self.printer.in_value { + write!(self.printer, "::<")?; + } else { + write!(self.printer, "<")?; + } + + let was_in_value = std::mem::replace(&mut self.printer.in_value, false); + let mut printer = f(self)?; + printer.in_value = was_in_value; + + write!(printer, ">")?; + Ok(printer) + } + + fn always_print_region_in_paths( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool { + *region != ty::ReErased + } + + fn print_region_outputs_anything( + self: &PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> bool { + let highlight = self.printer.region_highlight_mode; + if highlight.region_highlighted(region).is_some() { + return true; + } + + if self.config.is_verbose { + return true; + } + + match *region { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } + + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } + + ty::ReScope(_) | + ty::ReVar(_) if self.config.identify_regions => true, + + ty::ReVar(_) | + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. +impl FmtPrinter { + pub fn pretty_print_region( + mut self: PrintCx<'_, '_, '_, Self>, + region: ty::Region<'_>, + ) -> Result { + define_scoped_cx!(self); + + // Watch out for region highlights. + let highlight = self.printer.region_highlight_mode; + if let Some(n) = highlight.region_highlighted(region) { + p!(write("'{}", n)); + return Ok(self.printer); + } + + if self.config.is_verbose { + return region.print_debug(self); + } + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *region { + ty::ReEarlyBound(ref data) => { + if data.name != "'_" { + p!(write("{}", data.name)); + } + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + p!(write("{}", name)); + return Ok(self.printer); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + p!(write("'{}", counter)); + } + } + } + ty::ReScope(scope) if self.config.identify_regions => { + match scope.data { + region::ScopeData::Node => + p!(write("'{}s", scope.item_local_id().as_usize())), + region::ScopeData::CallSite => + p!(write("'{}cs", scope.item_local_id().as_usize())), + region::ScopeData::Arguments => + p!(write("'{}as", scope.item_local_id().as_usize())), + region::ScopeData::Destruction => + p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => p!(write( + "'{}_{}rs", + scope.item_local_id().as_usize(), + first_statement_index.index() + )), + } + } + ty::ReVar(region_vid) if self.config.identify_regions => { + p!(write("{:?}", region_vid)); + } + ty::ReVar(_) => {} + ty::ReScope(_) | + ty::ReErased => {} + ty::ReStatic => p!(write("'static")), + ty::ReEmpty => p!(write("'")), + + // The user should never encounter these in unsubstituted form. + ty::ReClosureBound(vid) => p!(write("{:?}", vid)), + } + + Ok(self.printer) + } +} + +impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { + pub fn pretty_print_type( + mut self, + ty: Ty<'tcx>, + ) -> Result { + define_scoped_cx!(self); + + match ty.sty { + ty::Bool => p!(write("bool")), + ty::Char => p!(write("char")), + ty::Int(t) => p!(write("{}", t.ty_to_string())), + ty::Uint(t) => p!(write("{}", t.ty_to_string())), + ty::Float(t) => p!(write("{}", t.ty_to_string())), + ty::RawPtr(ref tm) => { + p!(write("*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })); + p!(print(tm.ty)) + } + ty::Ref(r, ty, mutbl) => { + p!(write("&")); + if self.print_region_outputs_anything(r) { + p!(print_display(r), write(" ")); + } + p!(print(ty::TypeAndMut { ty, mutbl })) + } + ty::Never => p!(write("!")), + ty::Tuple(ref tys) => { + p!(write("(")); + let mut tys = tys.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty), write(",")); + if let Some(&ty) = tys.next() { + p!(write(" "), print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } + } + p!(write(")")) + } + ty::FnDef(def_id, substs) => { + let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); + p!(print(sig), write(" {{")); + nest!(|cx| cx.print_value_path(def_id, Some(substs))); + p!(write("}}")) + } + ty::FnPtr(ref bare_fn) => { + p!(print(bare_fn)) + } + ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Error => p!(write("[type error]")), + ty::Param(ref param_ty) => p!(write("{}", param_ty)), + ty::Bound(debruijn, bound_ty) => { + match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) + } + } + + ty::BoundTyKind::Param(p) => p!(write("{}", p)), + } + } + ty::Adt(def, substs) => { + nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); + } + ty::Dynamic(data, r) => { + let print_r = self.print_region_outputs_anything(r); + if print_r { + p!(write("(")); + } + p!(write("dyn "), print(data)); + if print_r { + p!(write(" + "), print_display(r), write(")")); + } + } + ty::Foreign(def_id) => { + nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); + } + ty::Projection(ref data) => p!(print(data)), + ty::UnnormalizedProjection(ref data) => { + p!(write("Unnormalized("), print(data), write(")")) + } + ty::Placeholder(placeholder) => { + p!(write("Placeholder({:?})", placeholder)) + } + ty::Opaque(def_id, substs) => { + if self.config.is_verbose { + p!(write("Opaque({:?}, {:?})", def_id, substs)); + return Ok(self.printer); + } + + let def_key = self.tcx.def_key(def_id); + if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { + p!(write("{}", name)); + let mut substs = substs.iter(); + // FIXME(eddyb) print this with `print_def_path`. + if let Some(first) = substs.next() { + p!(write("::<")); + p!(print_display(first)); + for subst in substs { + p!(write(", "), print_display(subst)); + } + p!(write(">")); + } + return Ok(self.printer); + } + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); + + let mut first = true; + let mut is_sized = false; + p!(write("impl")); + for predicate in bounds.predicates { + if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { + // Don't print +Sized, but rather +?Sized if absent. + if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + is_sized = true; + continue; + } + + p!( + write("{}", if first { " " } else { "+" }), + print(trait_ref)); + first = false; + } + } + if !is_sized { + p!(write("{}?Sized", if first { " " } else { "+" })); + } else if first { + p!(write(" Sized")); + } + } + ty::Str => p!(write("str")), + ty::Generator(did, substs, movability) => { + let upvar_tys = substs.upvar_tys(did, self.tcx); + let witness = substs.witness(did, self.tcx); + if movability == hir::GeneratorMovability::Movable { + p!(write("[generator")); + } else { + p!(write("[static generator")); + } + + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { + p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), + print(upvar_ty)); + sep = ", "; + } + } + + p!(write(" "), print(witness), write("]")) + }, + ty::GeneratorWitness(types) => { + nest!(|cx| cx.pretty_in_binder(&types)) + } + ty::Closure(did, substs) => { + let upvar_tys = substs.upvar_tys(did, self.tcx); + p!(write("[closure")); + + // FIXME(eddyb) should use `def_span`. + if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { + if self.tcx.sess.opts.debugging_opts.span_free_formats { + p!(write("@{:?}", hir_id)); + } else { + p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + } + let mut sep = " "; + for (freevar, upvar_ty) in self.tcx.freevars(did) + .as_ref() + .map_or(&[][..], |fv| &fv[..]) + .iter() + .zip(upvar_tys) + { + p!( + write("{}{}:", + sep, + self.tcx.hir().name(freevar.var_id())), + print(upvar_ty)); + sep = ", "; + } + } else { + // cross-crate closure types should only be + // visible in codegen bug reports, I imagine. + p!(write("@{:?}", did)); + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + p!( + write("{}{}:", sep, index), + print(upvar_ty)); + sep = ", "; + } + } + + if self.config.is_verbose { + p!(write( + " closure_kind_ty={:?} closure_sig_ty={:?}", + substs.closure_kind_ty(did, self.tcx), + substs.closure_sig_ty(did, self.tcx) + )); + } + + p!(write("]")) + }, + ty::Array(ty, sz) => { + p!(write("["), print(ty), write("; ")); + match sz { + ty::LazyConst::Unevaluated(_def_id, _substs) => { + p!(write("_")); + } + ty::LazyConst::Evaluated(c) => { + match c.val { + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => + p!(write("{}", name)), + _ => p!(write("{}", c.unwrap_usize(self.tcx))), + } + } + } + p!(write("]")) + } + ty::Slice(ty) => { + p!(write("["), print(ty), write("]")) + } + } + + Ok(self.printer) + } + + pub fn pretty_fn_sig( + mut self, + inputs: &[Ty<'tcx>], + c_variadic: bool, + output: Ty<'tcx>, + ) -> Result { + define_scoped_cx!(self); + + p!(write("(")); + let mut inputs = inputs.iter(); + if let Some(&ty) = inputs.next() { + p!(print_display(ty)); + for &ty in inputs { + p!(write(", "), print_display(ty)); + } + if c_variadic { + p!(write(", ...")); + } + } + p!(write(")")); + if !output.is_unit() { + p!(write(" -> "), print_display(output)); + } + + Ok(self.printer) + } + + pub fn pretty_in_binder(mut self, value: &ty::Binder) -> Result + where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx> + { + fn name_by_region_index(index: usize) -> InternedString { + match index { + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), + }.as_interned_str() + } + + // Replace any anonymous late-bound regions with named + // variants, using gensym'd identifiers, so that we can + // clearly differentiate between named and unnamed regions in + // the output. We'll probably want to tweak this over time to + // decide just how much information to give. + if self.config.binder_depth == 0 { + self.prepare_late_bound_region_info(value); + } + + let mut empty = true; + let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { + write!(cx.printer, "{}", if empty { + empty = false; + start + } else { + cont + }) + }; + + // NOTE(eddyb) this must be below `start_or_continue`'s definition + // as that also has a `define_scoped_cx` and that kind of shadowing + // is disallowed (name resolution thinks `scoped_cx!` is ambiguous). + define_scoped_cx!(self); + + let old_region_index = self.config.region_index; + let mut region_index = old_region_index; + let new_value = self.tcx.replace_late_bound_regions(value, |br| { + let _ = start_or_continue(&mut self, "for<", ", "); + let br = match br { + ty::BrNamed(_, name) => { + let _ = write!(self.printer, "{}", name); + br + } + ty::BrAnon(_) | + ty::BrFresh(_) | + ty::BrEnv => { + let name = loop { + let name = name_by_region_index(region_index); + region_index += 1; + if !self.is_name_used(&name) { + break name; + } + }; + let _ = write!(self.printer, "{}", name); + ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) + } + }; + self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) + }).0; + start_or_continue(&mut self, "", "> ")?; + + // Push current state to gcx, and restore after writing new_value. + self.config.binder_depth += 1; + self.config.region_index = region_index; + let result = new_value.print_display(PrintCx { + tcx: self.tcx, + printer: self.printer, + config: self.config, + }); + self.config.region_index = old_region_index; + self.config.binder_depth -= 1; + result + } + + fn is_name_used(&self, name: &InternedString) -> bool { + match self.config.used_region_names { + Some(ref names) => names.contains(name), + None => false, + } + } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 204a9574a64f0..059a3614704bb 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,18 +1,15 @@ +use crate::hir; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; -use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; -use crate::ty::{self, ParamConst, Ty, TypeFoldable}; +use crate::ty::subst::{Kind, SubstsRef, UnpackedKind}; +use crate::ty::{self, ParamConst, Ty}; use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; use crate::mir::interpret::ConstValue; use std::fmt::{self, Write as _}; use std::iter; -use std::usize; use rustc_target::spec::abi::Abi; -use syntax::ast::CRATE_NODE_ID; -use syntax::symbol::{Symbol, InternedString}; -use crate::hir; macro_rules! gen_display_debug_body { ( $with:path ) => { @@ -145,117 +142,6 @@ macro_rules! define_scoped_cx { }; } -impl PrintCx<'a, 'gcx, 'tcx, P> { - fn fn_sig( - mut self, - inputs: &[Ty<'tcx>], - c_variadic: bool, - output: Ty<'tcx>, - ) -> Result { - define_scoped_cx!(self); - - p!(write("(")); - let mut inputs = inputs.iter(); - if let Some(&ty) = inputs.next() { - p!(print_display(ty)); - for &ty in inputs { - p!(write(", "), print_display(ty)); - } - if c_variadic { - p!(write(", ...")); - } - } - p!(write(")")); - if !output.is_unit() { - p!(write(" -> "), print_display(output)); - } - - Ok(self.printer) - } - - fn in_binder(mut self, value: &ty::Binder) -> Result - where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx> - { - fn name_by_region_index(index: usize) -> InternedString { - match index { - 0 => Symbol::intern("'r"), - 1 => Symbol::intern("'s"), - i => Symbol::intern(&format!("'t{}", i-2)), - }.as_interned_str() - } - - // Replace any anonymous late-bound regions with named - // variants, using gensym'd identifiers, so that we can - // clearly differentiate between named and unnamed regions in - // the output. We'll probably want to tweak this over time to - // decide just how much information to give. - if self.config.binder_depth == 0 { - self.prepare_late_bound_region_info(value); - } - - let mut empty = true; - let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - write!(cx.printer, "{}", if empty { - empty = false; - start - } else { - cont - }) - }; - - // NOTE(eddyb) this must be below `start_or_continue`'s definition - // as that also has a `define_scoped_cx` and that kind of shadowing - // is disallowed (name resolution thinks `scoped_cx!` is ambiguous). - define_scoped_cx!(self); - - let old_region_index = self.config.region_index; - let mut region_index = old_region_index; - let new_value = self.tcx.replace_late_bound_regions(value, |br| { - let _ = start_or_continue(&mut self, "for<", ", "); - let br = match br { - ty::BrNamed(_, name) => { - let _ = write!(self.printer, "{}", name); - br - } - ty::BrAnon(_) | - ty::BrFresh(_) | - ty::BrEnv => { - let name = loop { - let name = name_by_region_index(region_index); - region_index += 1; - if !self.is_name_used(&name) { - break name; - } - }; - let _ = write!(self.printer, "{}", name); - ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name) - } - }; - self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) - }).0; - start_or_continue(&mut self, "", "> ")?; - - // Push current state to gcx, and restore after writing new_value. - self.config.binder_depth += 1; - self.config.region_index = region_index; - let result = new_value.print_display(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - }); - self.config.region_index = old_region_index; - self.config.binder_depth -= 1; - result - } - - fn is_name_used(&self, name: &InternedString) -> bool { - match self.config.used_region_names { - Some(ref names) => names.contains(name), - None => false, - } - } -} - pub fn parameterized( f: &mut F, did: DefId, @@ -285,7 +171,7 @@ define_print! { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); - nest!(|cx| cx.fn_sig(args, false, proj.ty)); + nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); resugared_principal = true; } } @@ -535,7 +421,7 @@ define_print! { } p!(write("fn")); - nest!(|cx| cx.fn_sig(self.inputs(), self.c_variadic, self.output())); + nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } debug { p!(write("({:?}; c_variadic: {})->{:?}", @@ -624,7 +510,7 @@ impl fmt::Debug for ty::FloatVarValue { for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(|cx| cx.in_binder(cx.tcx.lift(self) + PrintCx::with_tls_tcx(|cx| cx.pretty_in_binder(cx.tcx.lift(self) .expect("could not lift for printing"))) } }*/ @@ -642,7 +528,7 @@ define_print_multi! { ] (self, cx) { display { - nest!(|cx| cx.in_binder(self)) + nest!(|cx| cx.pretty_in_binder(self)) } } } @@ -658,264 +544,6 @@ define_print! { } } -// FIXME(eddyb) move this to `ty::print`. -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { - pub fn pretty_print_type( - mut self, - ty: Ty<'tcx>, - ) -> Result { - define_scoped_cx!(self); - - match ty.sty { - ty::Bool => p!(write("bool")), - ty::Char => p!(write("char")), - ty::Int(t) => p!(write("{}", t.ty_to_string())), - ty::Uint(t) => p!(write("{}", t.ty_to_string())), - ty::Float(t) => p!(write("{}", t.ty_to_string())), - ty::RawPtr(ref tm) => { - p!(write("*{} ", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - })); - p!(print(tm.ty)) - } - ty::Ref(r, ty, mutbl) => { - p!(write("&")); - if self.print_region_outputs_anything(r) { - p!(print_display(r), write(" ")); - } - p!(print(ty::TypeAndMut { ty, mutbl })) - } - ty::Never => p!(write("!")), - ty::Tuple(ref tys) => { - p!(write("(")); - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - p!(print(ty), write(",")); - if let Some(&ty) = tys.next() { - p!(write(" "), print(ty)); - for &ty in tys { - p!(write(", "), print(ty)); - } - } - } - p!(write(")")) - } - ty::FnDef(def_id, substs) => { - let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); - p!(print(sig), write(" {{")); - nest!(|cx| cx.print_value_path(def_id, Some(substs))); - p!(write("}}")) - } - ty::FnPtr(ref bare_fn) => { - p!(print(bare_fn)) - } - ty::Infer(infer_ty) => p!(write("{}", infer_ty)), - ty::Error => p!(write("[type error]")), - ty::Param(ref param_ty) => p!(write("{}", param_ty)), - ty::Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - p!(write("^{}", bound_ty.var.index())) - } else { - p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) - } - } - - ty::BoundTyKind::Param(p) => p!(write("{}", p)), - } - } - ty::Adt(def, substs) => { - nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); - } - ty::Dynamic(data, r) => { - let print_r = self.print_region_outputs_anything(r); - if print_r { - p!(write("(")); - } - p!(write("dyn "), print(data)); - if print_r { - p!(write(" + "), print_display(r), write(")")); - } - } - ty::Foreign(def_id) => { - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); - } - ty::Projection(ref data) => p!(print(data)), - ty::UnnormalizedProjection(ref data) => { - p!(write("Unnormalized("), print(data), write(")")) - } - ty::Placeholder(placeholder) => { - p!(write("Placeholder({:?})", placeholder)) - } - ty::Opaque(def_id, substs) => { - if self.config.is_verbose { - p!(write("Opaque({:?}, {:?})", def_id, substs)); - return Ok(self.printer); - } - - let def_key = self.tcx.def_key(def_id); - if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - p!(write("{}", name)); - let mut substs = substs.iter(); - // FIXME(eddyb) print this with `print_def_path`. - if let Some(first) = substs.next() { - p!(write("::<")); - p!(print_display(first)); - for subst in substs { - p!(write(", "), print_display(subst)); - } - p!(write(">")); - } - return Ok(self.printer); - } - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); - - let mut first = true; - let mut is_sized = false; - p!(write("impl")); - for predicate in bounds.predicates { - if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { - is_sized = true; - continue; - } - - p!( - write("{}", if first { " " } else { "+" }), - print(trait_ref)); - first = false; - } - } - if !is_sized { - p!(write("{}?Sized", if first { " " } else { "+" })); - } else if first { - p!(write(" Sized")); - } - } - ty::Str => p!(write("str")), - ty::Generator(did, substs, movability) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); - let witness = substs.witness(did, self.tcx); - if movability == hir::GeneratorMovability::Movable { - p!(write("[generator")); - } else { - p!(write("[static generator")); - } - - // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); - let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) - .as_ref() - .map_or(&[][..], |fv| &fv[..]) - .iter() - .zip(upvar_tys) - { - p!( - write("{}{}:", - sep, - self.tcx.hir().name(freevar.var_id())), - print(upvar_ty)); - sep = ", "; - } - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); - sep = ", "; - } - } - - p!(write(" "), print(witness), write("]")) - }, - ty::GeneratorWitness(types) => { - nest!(|cx| cx.in_binder(&types)) - } - ty::Closure(did, substs) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); - p!(write("[closure")); - - // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - if self.tcx.sess.opts.debugging_opts.span_free_formats { - p!(write("@{:?}", hir_id)); - } else { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); - } - let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) - .as_ref() - .map_or(&[][..], |fv| &fv[..]) - .iter() - .zip(upvar_tys) - { - p!( - write("{}{}:", - sep, - self.tcx.hir().name(freevar.var_id())), - print(upvar_ty)); - sep = ", "; - } - } else { - // cross-crate closure types should only be - // visible in codegen bug reports, I imagine. - p!(write("@{:?}", did)); - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); - sep = ", "; - } - } - - if self.config.is_verbose { - p!(write( - " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, self.tcx), - substs.closure_sig_ty(did, self.tcx) - )); - } - - p!(write("]")) - }, - ty::Array(ty, sz) => { - p!(write("["), print(ty), write("; ")); - match sz { - ty::LazyConst::Unevaluated(_def_id, _substs) => { - p!(write("_")); - } - ty::LazyConst::Evaluated(c) => { - match c.val { - ConstValue::Infer(..) => p!(write("_")), - ConstValue::Param(ParamConst { name, .. }) => - p!(write("{}", name)), - _ => p!(write("{}", c.unwrap_usize(self.tcx))), - } - } - } - p!(write("]")) - } - ty::Slice(ty) => { - p!(write("["), print(ty), write("]")) - } - } - - Ok(self.printer) - } -} - define_print! { ('tcx) Ty<'tcx>, (self, cx) { display { From 800ddb367e4a56a77ab940ce95023e82b64f3bd2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Jan 2019 21:45:13 +0200 Subject: [PATCH 131/157] rustc: remove fields from ty::print::PrintConfig available from tcx. --- src/librustc/mir/mod.rs | 28 ++++++++++++++-------------- src/librustc/ty/print/mod.rs | 18 ++---------------- src/librustc/ty/print/pretty.rs | 18 +++++++++++------- src/librustc/util/ppaux.rs | 4 ++-- 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0165bba5ed7e3..c0f0df004c670 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2369,20 +2369,20 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; // When printing regions, add trailing space if necessary. - let ns = Namespace::ValueNS; - ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt, ns), |mut cx| { - let region = if cx.config.is_verbose || cx.config.identify_regions { - let mut region = region.to_string(); - if region.len() > 0 { - region.push(' '); - } - region - } else { - // Do not even print 'static - String::new() - }; - write!(cx.printer, "&{}{}{:?}", region, kind_str, place) - }) + let print_region = ty::tls::with(|tcx| { + tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions + }); + let region = if print_region { + let mut region = region.to_string(); + if region.len() > 0 { + region.push(' '); + } + region + } else { + // Do not even print 'static + String::new() + }; + write!(fmt, "&{}{}{:?}", region, kind_str, place) } Aggregate(ref kind, ref places) => { diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 9d93d1a34a13a..ccd2a702c9f26 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -29,28 +29,14 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { } } +#[derive(Default)] pub(crate) struct PrintConfig { pub(crate) is_debug: bool, - pub(crate) is_verbose: bool, - pub(crate) identify_regions: bool, used_region_names: Option>, region_index: usize, binder_depth: usize, } -impl PrintConfig { - fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { - PrintConfig { - is_debug: false, - is_verbose: tcx.sess.verbose(), - identify_regions: tcx.sess.opts.debugging_opts.identify_regions, - used_region_names: None, - region_index: 0, - binder_depth: 0, - } - } -} - pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub printer: P, @@ -75,7 +61,7 @@ impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { f(PrintCx { tcx, printer, - config: &mut PrintConfig::new(tcx), + config: &mut PrintConfig::default(), }) } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index caa4090625d91..325897dc042f1 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -515,7 +515,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }); // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = if self.config.is_verbose { + let num_supplied_defaults = if self.tcx.sess.verbose() { 0 } else { params.iter().rev().take_while(|param| { @@ -818,10 +818,12 @@ impl PrettyPrinter for FmtPrinter { return true; } - if self.config.is_verbose { + if self.tcx.sess.verbose() { return true; } + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + match *region { ty::ReEarlyBound(ref data) => { data.name != "" && data.name != "'_" @@ -846,7 +848,7 @@ impl PrettyPrinter for FmtPrinter { } ty::ReScope(_) | - ty::ReVar(_) if self.config.identify_regions => true, + ty::ReVar(_) if identify_regions => true, ty::ReVar(_) | ty::ReScope(_) | @@ -874,10 +876,12 @@ impl FmtPrinter { return Ok(self.printer); } - if self.config.is_verbose { + if self.tcx.sess.verbose() { return region.print_debug(self); } + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + // These printouts are concise. They do not contain all the information // the user might want to diagnose an error, but there is basically no way // to fit that into a short string. Hence the recommendation to use @@ -904,7 +908,7 @@ impl FmtPrinter { } } } - ty::ReScope(scope) if self.config.identify_regions => { + ty::ReScope(scope) if identify_regions => { match scope.data { region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())), @@ -921,7 +925,7 @@ impl FmtPrinter { )), } } - ty::ReVar(region_vid) if self.config.identify_regions => { + ty::ReVar(region_vid) if identify_regions => { p!(write("{:?}", region_vid)); } ty::ReVar(_) => {} @@ -1029,7 +1033,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write("Placeholder({:?})", placeholder)) } ty::Opaque(def_id, substs) => { - if self.config.is_verbose { + if self.tcx.sess.verbose() { p!(write("Opaque({:?}, {:?})", def_id, substs)); return Ok(self.printer); } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 059a3614704bb..20df306dd2aff 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -166,7 +166,7 @@ define_print! { // Special-case `Fn(...) -> ...` and resugar it. let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); - if !cx.config.is_verbose && fn_trait_kind.is_some() { + if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { @@ -463,7 +463,7 @@ impl fmt::Debug for ty::RegionVid { define_print! { () ty::InferTy, (self, cx) { display { - if cx.config.is_verbose { + if cx.tcx.sess.verbose() { return self.print_debug(cx); } match *self { From d0a1bf5c88a31942dc3e3e1fdd991c4fae5fded9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Jan 2019 22:14:01 +0200 Subject: [PATCH 132/157] rustc: make util::ppaux private. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc/mir/mod.rs | 9 +++++++-- src/librustc/traits/structural_impls.rs | 5 +++-- src/librustc/ty/instance.rs | 9 +++++++-- src/librustc/ty/print/pretty.rs | 2 +- src/librustc/util/ppaux.rs | 16 +--------------- src/librustc_mir/monomorphize/item.rs | 5 ++--- 8 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index ad24e15b45a51..73a8721bdeb2e 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -768,7 +768,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// For generic types with parameters with defaults, remove the parameters corresponding to - /// the defaults. This repeats a lot of the logic found in `PrintCx::parameterized`. + /// the defaults. This repeats a lot of the logic found in `ty::print::pretty`. fn strip_generic_default_params( &self, def_id: DefId, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 53f39d3ac8a37..9150417a85db6 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -135,7 +135,7 @@ pub mod ty; pub mod util { pub mod captures; pub mod common; - pub mod ppaux; + mod ppaux; pub mod nodemap; pub mod profiling; pub mod bug; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c0f0df004c670..5e2851e08ec4c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -34,7 +34,7 @@ use crate::ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; -use crate::util::ppaux; +use crate::ty::print::{FmtPrinter, Printer, PrintCx}; pub use crate::mir::interpret::AssertMessage; @@ -2406,7 +2406,12 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, variant_def.did, substs, Namespace::ValueNS)?; + let f = &mut *fmt; + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |cx| { + let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); + cx.print_def_path(variant_def.did, Some(substs), iter::empty())?; + Ok(()) + })?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index b5be1777fa0d8..f3a800bf46d87 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -165,7 +165,8 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { use crate::traits::WhereClause::*; - // Bypass ppaux because it does not print out anonymous regions. + // Bypass `ty::print` because it does not print out anonymous regions. + // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`. fn write_region_name<'tcx>( r: ty::Region<'tcx>, fmt: &mut fmt::Formatter<'_> @@ -256,7 +257,7 @@ impl fmt::Display for traits::QuantifierKind { } /// Collect names for regions / types bound by a quantified goal / clause. -/// This collector does not try to do anything clever like in ppaux, it's just used +/// This collector does not try to do anything clever like in `ty::print`, it's just used /// for debug output in tests anyway. struct BoundNamesCollector { // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index fd0b97e98a3f9..b137d5f69c641 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -2,10 +2,10 @@ use crate::hir::Unsafety; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; +use crate::ty::print::{FmtPrinter, Printer, PrintCx}; use crate::traits; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; -use crate::util::ppaux; use std::fmt; use std::iter; @@ -176,7 +176,12 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ppaux::parameterized(f, self.def_id(), self.substs, Namespace::ValueNS)?; + PrintCx::with_tls_tcx(FmtPrinter::new(&mut *f, Namespace::ValueNS), |cx| { + let substs = cx.tcx.lift(&self.substs).expect("could not lift for printing"); + cx.print_def_path(self.def_id(), Some(substs), iter::empty())?; + Ok(()) + })?; + match self.def { InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => { diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 325897dc042f1..a2e8954cf92ea 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1163,7 +1163,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - if self.config.is_verbose { + if self.tcx.sess.verbose() { p!(write( " closure_kind_ty={:?} closure_sig_ty={:?}", substs.closure_kind_ty(did, self.tcx), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 20df306dd2aff..cb2c8acba82dc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,7 +1,6 @@ use crate::hir; use crate::hir::def::Namespace; -use crate::hir::def_id::DefId; -use crate::ty::subst::{Kind, SubstsRef, UnpackedKind}; +use crate::ty::subst::{Kind, UnpackedKind}; use crate::ty::{self, ParamConst, Ty}; use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; use crate::mir::interpret::ConstValue; @@ -142,19 +141,6 @@ macro_rules! define_scoped_cx { }; } -pub fn parameterized( - f: &mut F, - did: DefId, - substs: SubstsRef<'_>, - ns: Namespace, -) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, ns), |cx| { - let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.print_def_path(did, Some(substs), iter::empty())?; - Ok(()) - }) -} - define_print! { ('tcx) &'tcx ty::List>, (self, cx) { display { diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 211f9ad1735c3..68d13bf2dcb24 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -216,9 +216,8 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { // These keys are used by the handwritten auto-tests, so they need to be // predictable and human-readable. // -// Note: A lot of this could looks very similar to what's already in the -// ppaux module. It would be good to refactor things so we only have one -// parameterizable implementation for printing types. +// Note: A lot of this could looks very similar to what's already in `ty::print`. +// FIXME(eddyb) implement a custom `PrettyPrinter` for this. /// Same as `unique_type_name()` but with the result pushed onto the given /// `output` parameter. From 9c424850e8b342eb348c4a8cbb95704f51aedac3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 19 Jan 2019 03:25:51 +0200 Subject: [PATCH 133/157] rustc: disconnect all the Debug functionality from ty::print. --- src/librustc/ty/print/mod.rs | 26 --- src/librustc/ty/print/pretty.rs | 34 ++-- src/librustc/util/ppaux.rs | 291 ++++++++++++++------------------ 3 files changed, 141 insertions(+), 210 deletions(-) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index ccd2a702c9f26..8c590bd783315 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -31,7 +31,6 @@ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { #[derive(Default)] pub(crate) struct PrintConfig { - pub(crate) is_debug: bool, used_region_names: Option>, region_index: usize, binder_depth: usize, @@ -83,31 +82,6 @@ pub trait Print<'tcx, P> { type Error; fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result; - fn print_display( - &self, - cx: PrintCx<'_, '_, 'tcx, P>, - ) -> Result { - let old_debug = cx.config.is_debug; - cx.config.is_debug = false; - let result = self.print(PrintCx { - tcx: cx.tcx, - printer: cx.printer, - config: cx.config, - }); - cx.config.is_debug = old_debug; - result - } - fn print_debug(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { - let old_debug = cx.config.is_debug; - cx.config.is_debug = true; - let result = self.print(PrintCx { - tcx: cx.tcx, - printer: cx.printer, - config: cx.config, - }); - cx.config.is_debug = old_debug; - result - } } pub trait Printer: Sized { diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index a2e8954cf92ea..6a7c48ee87940 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -451,7 +451,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ty::Adt(..) | ty::Foreign(_) | ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { - return self_ty.print_display(self); + return self_ty.print(self); } _ => {} @@ -461,9 +461,9 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self.generic_delimiters(|mut cx| { define_scoped_cx!(cx); - p!(print_display(self_ty)); + p!(print(self_ty)); if let Some(trait_ref) = trait_ref { - p!(write(" as "), print_display(trait_ref)); + p!(write(" as "), print(trait_ref)); } Ok(cx.printer) }) @@ -484,9 +484,9 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write("impl ")); if let Some(trait_ref) = trait_ref { - p!(print_display(trait_ref), write(" for ")); + p!(print(trait_ref), write(" for ")); } - p!(print_display(self_ty)); + p!(print(self_ty)); Ok(cx.printer) }) @@ -578,14 +578,14 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - p!(print_display(arg)); + p!(print(arg)); } for projection in projection0.into_iter().chain(projections) { maybe_comma(&mut cx)?; p!(write("{}=", cx.tcx.associated_item(projection.item_def_id).ident), - print_display(projection.ty)); + print(projection.ty)); } Ok(cx.printer) @@ -877,7 +877,8 @@ impl FmtPrinter { } if self.tcx.sess.verbose() { - return region.print_debug(self); + p!(write("{:?}", region)); + return Ok(self.printer); } let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; @@ -965,7 +966,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ty::Ref(r, ty, mutbl) => { p!(write("&")); if self.print_region_outputs_anything(r) { - p!(print_display(r), write(" ")); + p!(print(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) } @@ -1019,7 +1020,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(write("dyn "), print(data)); if print_r { - p!(write(" + "), print_display(r), write(")")); + p!(write(" + "), print(r), write(")")); } } ty::Foreign(def_id) => { @@ -1033,6 +1034,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write("Placeholder({:?})", placeholder)) } ty::Opaque(def_id, substs) => { + // FIXME(eddyb) print this with `print_def_path`. if self.tcx.sess.verbose() { p!(write("Opaque({:?}, {:?})", def_id, substs)); return Ok(self.printer); @@ -1045,9 +1047,9 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // FIXME(eddyb) print this with `print_def_path`. if let Some(first) = substs.next() { p!(write("::<")); - p!(print_display(first)); + p!(print(first)); for subst in substs { - p!(write(", "), print_display(subst)); + p!(write(", "), print(subst)); } p!(write(">")); } @@ -1209,9 +1211,9 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write("(")); let mut inputs = inputs.iter(); if let Some(&ty) = inputs.next() { - p!(print_display(ty)); + p!(print(ty)); for &ty in inputs { - p!(write(", "), print_display(ty)); + p!(write(", "), print(ty)); } if c_variadic { p!(write(", ...")); @@ -1219,7 +1221,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(write(")")); if !output.is_unit() { - p!(write(" -> "), print_display(output)); + p!(write(" -> "), print(output)); } Ok(self.printer) @@ -1290,7 +1292,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // Push current state to gcx, and restore after writing new_value. self.config.binder_depth += 1; self.config.region_index = region_index; - let result = new_value.print_display(PrintCx { + let result = new_value.print(PrintCx { tcx: self.tcx, printer: self.printer, config: self.config, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index cb2c8acba82dc..4c9d26c84816c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -10,108 +10,64 @@ use std::iter; use rustc_target::spec::abi::Abi; -macro_rules! gen_display_debug_body { - ( $with:path ) => { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?; - Ok(()) - }) - } - }; -} -macro_rules! gen_display_debug { - ( ($($x:tt)+) $target:ty, display yes ) => { - impl<$($x)+> fmt::Display for $target { - gen_display_debug_body! { Print::print_display } - } - }; - ( () $target:ty, display yes ) => { - impl fmt::Display for $target { - gen_display_debug_body! { Print::print_display } - } - }; - ( ($($x:tt)+) $target:ty, debug yes ) => { - impl<$($x)+> fmt::Debug for $target { - gen_display_debug_body! { Print::print_debug } - } - }; - ( () $target:ty, debug yes ) => { - impl fmt::Debug for $target { - gen_display_debug_body! { Print::print_debug } - } - }; - ( $generic:tt $target:ty, $t:ident no ) => {}; -} -macro_rules! gen_print_impl { - ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { - impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { +macro_rules! define_print { + (@display $target:ty, ($self:ident, $cx:ident) $disp:block) => { + impl Print<'tcx, P> for $target { type Output = P; type Error = fmt::Error; fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { #[allow(unused_mut)] let mut $cx = $cx; - let _: () = { - define_scoped_cx!($cx); - - if $cx.config.is_debug $dbg - else $disp - }; + define_scoped_cx!($cx); + let _: () = $disp; + #[allow(unreachable_code)] Ok($cx.printer) } } - }; - ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { - impl Print<'tcx, P> for $target { - type Output = P; - type Error = fmt::Error; - fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { - #[allow(unused_mut)] - let mut $cx = $cx; - let _: () = { - define_scoped_cx!($cx); - if $cx.config.is_debug $dbg - else $disp - }; - Ok($cx.printer) + impl fmt::Display for $target { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; + Ok(()) + }) } } }; - ( $generic:tt $target:ty, - $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => { - gen_print_impl! { $generic $target, $vars $disp $dbg } - gen_display_debug! { $generic $target, display $gendisp } - gen_display_debug! { $generic $target, debug $gendbg } - } -} -macro_rules! define_print { - ( $generic:tt $target:ty, - $vars:tt { display $disp:block debug $dbg:block } ) => { - gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } - }; - ( $generic:tt $target:ty, - $vars:tt { debug $dbg:block display $disp:block } ) => { - gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } + + (@debug $target:ty, ($self:ident, $cx:ident) $dbg:block) => { + impl fmt::Debug for $target { + fn fmt(&$self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |$cx| { + #[allow(unused_mut)] + let mut $cx = $cx; + define_scoped_cx!($cx); + let _: () = $dbg; + let _ = $cx; + Ok(()) + }) + } + } }; - ( $generic:tt $target:ty, - $vars:tt { debug $dbg:block } ) => { - gen_print_impl! { $generic $target, $vars no { - bug!(concat!("display not implemented for ", stringify!($target))); - } yes $dbg } + + ([$($target:ty),+] $vars:tt $def:tt) => { + $(define_print!($target, $vars $def);)+ }; - ( $generic:tt $target:ty, - ($self:ident, $cx:ident) { display $disp:block } ) => { - gen_print_impl! { $generic $target, ($self, $cx) yes $disp no { - write!($cx.printer, "{:?}", $self)? - } } + + ($target:ty, $vars:tt { + display $disp:block + debug $dbg:block + }) => { + define_print!(@display $target, $vars $disp); + define_print!(@debug $target, $vars $dbg); }; -} -macro_rules! define_print_multi { - ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => { - $(define_print! { $generic $target, $vars $def })* + ($target:ty, $vars:tt { + display $disp:block + }) => { + define_print!(@display $target, $vars $disp); }; } + macro_rules! nest { ($closure:expr) => { scoped_cx!() = scoped_cx!().nest($closure)? @@ -142,7 +98,7 @@ macro_rules! define_scoped_cx { } define_print! { - ('tcx) &'tcx ty::List>, (self, cx) { + &'tcx ty::List>, (self, cx) { display { // Generate the main trait ref, including associated types. let mut first = true; @@ -266,7 +222,7 @@ impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { } define_print! { - ('tcx) &'tcx ty::List>, (self, cx) { + &'tcx ty::List>, (self, cx) { display { p!(write("{{")); let mut tys = self.iter(); @@ -282,7 +238,7 @@ define_print! { } define_print! { - ('tcx) ty::TypeAndMut<'tcx>, (self, cx) { + ty::TypeAndMut<'tcx>, (self, cx) { display { p!( write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), @@ -292,26 +248,27 @@ define_print! { } define_print! { - ('tcx) ty::ExistentialTraitRef<'tcx>, (self, cx) { + ty::ExistentialTraitRef<'tcx>, (self, cx) { display { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let trait_ref = *ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) .skip_binder(); - p!(print_display(trait_ref)) - } - debug { - p!(print_display(self)) + p!(print(trait_ref)) } } } -define_print! { - ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) { - debug { - p!(write("{:?} -> ", self.kind), print(self.target)) - } +impl fmt::Debug for ty::ExistentialTraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Debug for ty::adjustment::Adjustment<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} -> {}", self.kind, self.target) } } @@ -330,7 +287,7 @@ impl fmt::Debug for ty::BoundRegion { } define_print! { - () ty::RegionKind, (self, cx) { + ty::RegionKind, (self, cx) { display { return cx.print_region(self); } @@ -350,7 +307,7 @@ define_print! { p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region)) } - ty::ReFree(ref fr) => p!(print_debug(fr)), + ty::ReFree(ref fr) => p!(write("{:?}", fr)), ty::ReScope(id) => { p!(write("ReScope({:?})", id)) @@ -374,29 +331,25 @@ define_print! { } } -define_print! { - () ty::FreeRegion, (self, cx) { - debug { - p!(write("ReFree({:?}, {:?})", self.scope, self.bound_region)) - } +impl fmt::Debug for ty::FreeRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) } } -define_print! { - () ty::Variance, (self, cx) { - debug { - cx.printer.write_str(match *self { - ty::Covariant => "+", - ty::Contravariant => "-", - ty::Invariant => "o", - ty::Bivariant => "*", - })? - } +impl fmt::Debug for ty::Variance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + ty::Covariant => "+", + ty::Contravariant => "-", + ty::Invariant => "o", + ty::Bivariant => "*", + }) } } define_print! { - ('tcx) ty::FnSig<'tcx>, (self, cx) { + ty::FnSig<'tcx>, (self, cx) { display { if self.unsafety == hir::Unsafety::Unsafe { p!(write("unsafe ")); @@ -447,10 +400,11 @@ impl fmt::Debug for ty::RegionVid { } define_print! { - () ty::InferTy, (self, cx) { + ty::InferTy, (self, cx) { display { if cx.tcx.sess.verbose() { - return self.print_debug(cx); + p!(write("{:?}", self)); + return Ok(cx.printer); } match *self { ty::TyVar(_) => p!(write("_")), @@ -501,16 +455,16 @@ impl fmt::Debug for ty::FloatVarValue { } }*/ -define_print_multi! { +define_print! { [ - ('tcx) ty::Binder<&'tcx ty::List>>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder>, - ('tcx) ty::Binder, ty::Region<'tcx>>>, - ('tcx) ty::Binder, ty::Region<'tcx>>> + ty::Binder<&'tcx ty::List>>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder, ty::Region<'tcx>>>, + ty::Binder, ty::Region<'tcx>>> ] (self, cx) { display { @@ -520,29 +474,35 @@ define_print_multi! { } define_print! { - ('tcx) ty::TraitRef<'tcx>, (self, cx) { + ty::TraitRef<'tcx>, (self, cx) { display { nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); } debug { - nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self))); + // HACK(eddyb) this is used across the compiler to print + // a `TraitRef` qualified (with the Self type explicit), + // instead of having a different way to make that choice. + p!(write("<{} as {}>", self.self_ty(), self)) } } } define_print! { - ('tcx) Ty<'tcx>, (self, cx) { + Ty<'tcx>, (self, cx) { display { return cx.print_type(self); } - debug { - p!(print_display(self)) - } + } +} + +impl fmt::Debug for Ty<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) } } define_print! { - ('tcx) ConstValue<'tcx>, (self, cx) { + ConstValue<'tcx>, (self, cx) { display { match self { ConstValue::Infer(..) => p!(write("_")), @@ -554,7 +514,7 @@ define_print! { } define_print! { - ('tcx) ty::Const<'tcx>, (self, cx) { + ty::Const<'tcx>, (self, cx) { display { p!(write("{} : {}", self.val, self.ty)) } @@ -562,7 +522,7 @@ define_print! { } define_print! { - ('tcx) ty::LazyConst<'tcx>, (self, cx) { + ty::LazyConst<'tcx>, (self, cx) { display { match self { // FIXME(const_generics) this should print at least the type. @@ -574,7 +534,7 @@ define_print! { } define_print! { - () ty::ParamTy, (self, cx) { + ty::ParamTy, (self, cx) { display { p!(write("{}", self.name)) } @@ -585,7 +545,7 @@ define_print! { } define_print! { - () ty::ParamConst, (self, cx) { + ty::ParamConst, (self, cx) { display { p!(write("{}", self.name)) } @@ -596,10 +556,10 @@ define_print! { } // Similar problem to `Binder`, can't define a generic impl. -define_print_multi! { +define_print! { [ - ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>>, - ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>> + ty::OutlivesPredicate, ty::Region<'tcx>>, + ty::OutlivesPredicate, ty::Region<'tcx>> ] (self, cx) { display { @@ -609,7 +569,7 @@ define_print_multi! { } define_print! { - ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) { + ty::SubtypePredicate<'tcx>, (self, cx) { display { p!(print(self.a), write(" <: "), print(self.b)) } @@ -617,35 +577,30 @@ define_print! { } define_print! { - ('tcx) ty::TraitPredicate<'tcx>, (self, cx) { + ty::TraitPredicate<'tcx>, (self, cx) { + display { + p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + } debug { p!(write("TraitPredicate({:?})", self.trait_ref)) } - display { - p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) - } } } define_print! { - ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) { - debug { - p!( - write("ProjectionPredicate("), - print(self.projection_ty), - write(", "), - print(self.ty), - write(")")) - } + ty::ProjectionPredicate<'tcx>, (self, cx) { display { p!(print(self.projection_ty), write(" == "), print(self.ty)) } + debug { + p!(write("ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)) + } } } define_print! { - ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { + ty::ProjectionTy<'tcx>, (self, cx) { display { nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); } @@ -653,7 +608,7 @@ define_print! { } define_print! { - () ty::ClosureKind, (self, cx) { + ty::ClosureKind, (self, cx) { display { match *self { ty::ClosureKind::Fn => p!(write("Fn")), @@ -665,7 +620,7 @@ define_print! { } define_print! { - ('tcx) ty::Predicate<'tcx>, (self, cx) { + ty::Predicate<'tcx>, (self, cx) { display { match *self { ty::Predicate::Trait(ref data) => p!(print(data)), @@ -693,12 +648,12 @@ define_print! { } debug { match *self { - ty::Predicate::Trait(ref a) => p!(print(a)), - ty::Predicate::Subtype(ref pair) => p!(print(pair)), - ty::Predicate::RegionOutlives(ref pair) => p!(print(pair)), - ty::Predicate::TypeOutlives(ref pair) => p!(print(pair)), - ty::Predicate::Projection(ref pair) => p!(print(pair)), - ty::Predicate::WellFormed(ty) => p!(print(ty)), + ty::Predicate::Trait(ref a) => p!(write("{:?}", a)), + ty::Predicate::Subtype(ref pair) => p!(write("{:?}", pair)), + ty::Predicate::RegionOutlives(ref pair) => p!(write("{:?}", pair)), + ty::Predicate::TypeOutlives(ref pair) => p!(write("{:?}", pair)), + ty::Predicate::Projection(ref pair) => p!(write("{:?}", pair)), + ty::Predicate::WellFormed(ty) => p!(write("WellFormed({:?})", ty)), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("ObjectSafe({:?})", trait_def_id)) } @@ -715,7 +670,7 @@ define_print! { } define_print! { - ('tcx) Kind<'tcx>, (self, cx) { + Kind<'tcx>, (self, cx) { display { match self.unpack() { UnpackedKind::Lifetime(lt) => p!(print(lt)), @@ -725,9 +680,9 @@ define_print! { } debug { match self.unpack() { - UnpackedKind::Lifetime(lt) => p!(print(lt)), - UnpackedKind::Type(ty) => p!(print(ty)), - UnpackedKind::Const(ct) => p!(print(ct)), + UnpackedKind::Lifetime(lt) => p!(write("{:?}", lt)), + UnpackedKind::Type(ty) => p!(write("{:?}", ty)), + UnpackedKind::Const(ct) => p!(write("{:?}", ct)), } } } From fb53bb9e2b67887916a9815428ff5b8bac4c1ebf Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 19 Jan 2019 06:33:44 +0200 Subject: [PATCH 134/157] rustc: move Debug impls from ppaux to ty::structural_impls. --- src/librustc/ty/structural_impls.rs | 270 +++++++++++++++++++++++++ src/librustc/ty/subst.rs | 11 ++ src/librustc/util/ppaux.rs | 294 +--------------------------- 3 files changed, 288 insertions(+), 287 deletions(-) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 43ab32237dea5..45db95e2b0f0f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -3,17 +3,287 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. +use crate::hir::def::Namespace; use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::print::{FmtPrinter, PrintCx, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use smallvec::SmallVec; use crate::mir::interpret; +use std::fmt; +use std::iter; use std::marker::PhantomData; use std::rc::Rc; +impl fmt::Debug for ty::GenericParamDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let type_name = match self.kind { + ty::GenericParamDefKind::Lifetime => "Lifetime", + ty::GenericParamDefKind::Type {..} => "Type", + ty::GenericParamDefKind::Const => "Const", + }; + write!(f, "{}({}, {:?}, {})", + type_name, + self.name, + self.def_id, + self.index) + } +} + +impl fmt::Debug for ty::TraitDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.print_def_path(self.def_id, None, iter::empty())?; + Ok(()) + }) + } +} + +impl fmt::Debug for ty::AdtDef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.print_def_path(self.did, None, iter::empty())?; + Ok(()) + }) + } +} + +impl fmt::Debug for ty::ClosureUpvar<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ClosureUpvar({:?},{:?})", + self.def, + self.ty) + } +} + +impl fmt::Debug for ty::UpvarId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = ty::tls::with(|tcx| { + tcx.hir().name_by_hir_id(self.var_path.hir_id) + }); + write!(f, "UpvarId({:?};`{}`;{:?})", + self.var_path.hir_id, + name, + self.closure_expr_id) + } +} + +impl fmt::Debug for ty::UpvarBorrow<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "UpvarBorrow({:?}, {:?})", + self.kind, self.region) + } +} + +impl fmt::Debug for ty::ExistentialTraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Debug for ty::adjustment::Adjustment<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?} -> {}", self.kind, self.target) + } +} + +impl fmt::Debug for ty::BoundRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), + ty::BrFresh(n) => write!(f, "BrFresh({:?})", n), + ty::BrNamed(did, name) => { + write!(f, "BrNamed({:?}:{:?}, {})", + did.krate, did.index, name) + } + ty::BrEnv => write!(f, "BrEnv"), + } + } +} + +impl fmt::Debug for ty::RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::ReEarlyBound(ref data) => { + write!(f, "ReEarlyBound({}, {})", + data.index, + data.name) + } + + ty::ReClosureBound(ref vid) => { + write!(f, "ReClosureBound({:?})", vid) + } + + ty::ReLateBound(binder_id, ref bound_region) => { + write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region) + } + + ty::ReFree(ref fr) => fr.fmt(f), + + ty::ReScope(id) => write!(f, "ReScope({:?})", id), + + ty::ReStatic => write!(f, "ReStatic"), + + ty::ReVar(ref vid) => vid.fmt(f), + + ty::RePlaceholder(placeholder) => { + write!(f, "RePlaceholder({:?})", placeholder) + } + + ty::ReEmpty => write!(f, "ReEmpty"), + + ty::ReErased => write!(f, "ReErased"), + } + } +} + +impl fmt::Debug for ty::FreeRegion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + } +} + +impl fmt::Debug for ty::Variance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + ty::Covariant => "+", + ty::Contravariant => "-", + ty::Invariant => "o", + ty::Bivariant => "*", + }) + } +} + +impl fmt::Debug for ty::FnSig<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({:?}; c_variadic: {})->{:?}", + self.inputs(), self.c_variadic, self.output()) + } +} + +impl fmt::Debug for ty::TyVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}t", self.index) + } +} + +impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}c", self.index) + } +} + +impl fmt::Debug for ty::IntVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}i", self.index) + } +} + +impl fmt::Debug for ty::FloatVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "_#{}f", self.index) + } +} + +impl fmt::Debug for ty::RegionVid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'_#{}r", self.index()) + } +} + +impl fmt::Debug for ty::InferTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::TyVar(ref v) => v.fmt(f), + ty::IntVar(ref v) => v.fmt(f), + ty::FloatVar(ref v) => v.fmt(f), + ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), + ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), + ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v), + } + } +} + +impl fmt::Debug for ty::IntVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::IntType(ref v) => v.fmt(f), + ty::UintType(ref v) => v.fmt(f), + } + } +} + +impl fmt::Debug for ty::FloatVarValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Debug for ty::TraitRef<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // HACK(eddyb) this is used across the compiler to print + // a `TraitRef` qualified (with the Self type explicit), + // instead of having a different way to make that choice. + write!(f, "<{} as {}>", self.self_ty(), self) + } +} + +impl fmt::Debug for Ty<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Debug for ty::ParamTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.idx) + } +} + +impl fmt::Debug for ty::ParamConst { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}/#{}", self.name, self.index) + } +} + +impl fmt::Debug for ty::TraitPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "TraitPredicate({:?})", self.trait_ref) + } +} + +impl fmt::Debug for ty::ProjectionPredicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty) + } +} + +impl fmt::Debug for ty::Predicate<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ty::Predicate::Trait(ref a) => a.fmt(f), + ty::Predicate::Subtype(ref pair) => pair.fmt(f), + ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f), + ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f), + ty::Predicate::Projection(ref pair) => pair.fmt(f), + ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty), + ty::Predicate::ObjectSafe(trait_def_id) => { + write!(f, "ObjectSafe({:?})", trait_def_id) + } + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + write!(f, "ClosureKind({:?}, {:?}, {:?})", + closure_def_id, closure_substs, kind) + } + ty::Predicate::ConstEvaluatable(def_id, substs) => { + write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + } + } + } +} + /////////////////////////////////////////////////////////////////////////// // Atomic structs // diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 8c67cdf62b62f..8464286561469 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -12,6 +12,7 @@ use smallvec::SmallVec; use rustc_macros::HashStable; use core::intrinsics; +use std::fmt; use std::cmp::Ordering; use std::marker::PhantomData; use std::mem; @@ -69,6 +70,16 @@ impl<'tcx> UnpackedKind<'tcx> { } } +impl fmt::Debug for Kind<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.unpack() { + UnpackedKind::Lifetime(lt) => lt.fmt(f), + UnpackedKind::Type(ty) => ty.fmt(f), + UnpackedKind::Const(ct) => ct.fmt(f), + } + } +} + impl<'tcx> Ord for Kind<'tcx> { fn cmp(&self, other: &Kind<'_>) -> Ordering { self.unpack().cmp(&other.unpack()) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 4c9d26c84816c..2e11a3741369e 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -2,16 +2,20 @@ use crate::hir; use crate::hir::def::Namespace; use crate::ty::subst::{Kind, UnpackedKind}; use crate::ty::{self, ParamConst, Ty}; -use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; +use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print}; use crate::mir::interpret::ConstValue; -use std::fmt::{self, Write as _}; +use std::fmt; use std::iter; use rustc_target::spec::abi::Abi; macro_rules! define_print { - (@display $target:ty, ($self:ident, $cx:ident) $disp:block) => { + ([$($target:ty),+] $vars:tt $def:tt) => { + $(define_print!($target, $vars $def);)+ + }; + + ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { impl Print<'tcx, P> for $target { type Output = P; type Error = fmt::Error; @@ -34,38 +38,6 @@ macro_rules! define_print { } } }; - - (@debug $target:ty, ($self:ident, $cx:ident) $dbg:block) => { - impl fmt::Debug for $target { - fn fmt(&$self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |$cx| { - #[allow(unused_mut)] - let mut $cx = $cx; - define_scoped_cx!($cx); - let _: () = $dbg; - let _ = $cx; - Ok(()) - }) - } - } - }; - - ([$($target:ty),+] $vars:tt $def:tt) => { - $(define_print!($target, $vars $def);)+ - }; - - ($target:ty, $vars:tt { - display $disp:block - debug $dbg:block - }) => { - define_print!(@display $target, $vars $disp); - define_print!(@debug $target, $vars $dbg); - }; - ($target:ty, $vars:tt { - display $disp:block - }) => { - define_print!(@display $target, $vars $disp); - }; } macro_rules! nest { @@ -160,67 +132,6 @@ define_print! { } } -impl fmt::Debug for ty::GenericParamDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_name = match self.kind { - ty::GenericParamDefKind::Lifetime => "Lifetime", - ty::GenericParamDefKind::Type { .. } => "Type", - ty::GenericParamDefKind::Const => "Const", - }; - write!(f, "{}({}, {:?}, {})", - type_name, - self.name, - self.def_id, - self.index) - } -} - -impl fmt::Debug for ty::TraitDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.def_id, None, iter::empty())?; - Ok(()) - }) - } -} - -impl fmt::Debug for ty::AdtDef { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.did, None, iter::empty())?; - Ok(()) - }) - } -} - -impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ClosureUpvar({:?},{:?})", - self.def, - self.ty) - } -} - -impl fmt::Debug for ty::UpvarId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |mut cx| { - define_scoped_cx!(cx); - p!(write("UpvarId({:?};`{}`;{:?})", - self.var_path.hir_id, - cx.tcx.hir().name_by_hir_id(self.var_path.hir_id), - self.closure_expr_id)); - Ok(()) - }) - } -} - -impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UpvarBorrow({:?}, {:?})", - self.kind, self.region) - } -} - define_print! { &'tcx ty::List>, (self, cx) { display { @@ -260,91 +171,11 @@ define_print! { } } -impl fmt::Debug for ty::ExistentialTraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl fmt::Debug for ty::adjustment::Adjustment<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?} -> {}", self.kind, self.target) - } -} - -impl fmt::Debug for ty::BoundRegion { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), - ty::BrFresh(n) => write!(f, "BrFresh({:?})", n), - ty::BrNamed(did, name) => { - write!(f, "BrNamed({:?}:{:?}, {})", - did.krate, did.index, name) - } - ty::BrEnv => write!(f, "BrEnv"), - } - } -} - define_print! { ty::RegionKind, (self, cx) { display { return cx.print_region(self); } - debug { - match *self { - ty::ReEarlyBound(ref data) => { - p!(write("ReEarlyBound({}, {})", - data.index, - data.name)) - } - - ty::ReClosureBound(ref vid) => { - p!(write("ReClosureBound({:?})", vid)) - } - - ty::ReLateBound(binder_id, ref bound_region) => { - p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region)) - } - - ty::ReFree(ref fr) => p!(write("{:?}", fr)), - - ty::ReScope(id) => { - p!(write("ReScope({:?})", id)) - } - - ty::ReStatic => p!(write("ReStatic")), - - ty::ReVar(ref vid) => { - p!(write("{:?}", vid)); - } - - ty::RePlaceholder(placeholder) => { - p!(write("RePlaceholder({:?})", placeholder)) - } - - ty::ReEmpty => p!(write("ReEmpty")), - - ty::ReErased => p!(write("ReErased")) - } - } - } -} - -impl fmt::Debug for ty::FreeRegion { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) - } -} - -impl fmt::Debug for ty::Variance { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match *self { - ty::Covariant => "+", - ty::Contravariant => "-", - ty::Invariant => "o", - ty::Bivariant => "*", - }) } } @@ -362,40 +193,6 @@ define_print! { p!(write("fn")); nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } - debug { - p!(write("({:?}; c_variadic: {})->{:?}", - self.inputs(), self.c_variadic, self.output())) - } - } -} - -impl fmt::Debug for ty::TyVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}t", self.index) - } -} - -impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) - } -} - -impl fmt::Debug for ty::IntVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}i", self.index) - } -} - -impl fmt::Debug for ty::FloatVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) - } -} - -impl fmt::Debug for ty::RegionVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "'_#{}r", self.index()) } } @@ -415,31 +212,6 @@ define_print! { ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) } } - debug { - match *self { - ty::TyVar(ref v) => p!(write("{:?}", v)), - ty::IntVar(ref v) => p!(write("{:?}", v)), - ty::FloatVar(ref v) => p!(write("{:?}", v)), - ty::FreshTy(v) => p!(write("FreshTy({:?})", v)), - ty::FreshIntTy(v) => p!(write("FreshIntTy({:?})", v)), - ty::FreshFloatTy(v) => p!(write("FreshFloatTy({:?})", v)) - } - } - } -} - -impl fmt::Debug for ty::IntVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ty::IntType(ref v) => v.fmt(f), - ty::UintType(ref v) => v.fmt(f), - } - } -} - -impl fmt::Debug for ty::FloatVarValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) } } @@ -478,12 +250,6 @@ define_print! { display { nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); } - debug { - // HACK(eddyb) this is used across the compiler to print - // a `TraitRef` qualified (with the Self type explicit), - // instead of having a different way to make that choice. - p!(write("<{} as {}>", self.self_ty(), self)) - } } } @@ -495,12 +261,6 @@ define_print! { } } -impl fmt::Debug for Ty<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - define_print! { ConstValue<'tcx>, (self, cx) { display { @@ -538,9 +298,6 @@ define_print! { display { p!(write("{}", self.name)) } - debug { - p!(write("{}/#{}", self.name, self.idx)) - } } } @@ -549,9 +306,6 @@ define_print! { display { p!(write("{}", self.name)) } - debug { - p!(write("{}/#{}", self.name, self.index)) - } } } @@ -581,10 +335,6 @@ define_print! { display { p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) } - debug { - p!(write("TraitPredicate({:?})", - self.trait_ref)) - } } } @@ -593,9 +343,6 @@ define_print! { display { p!(print(self.projection_ty), write(" == "), print(self.ty)) } - debug { - p!(write("ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)) - } } } @@ -646,26 +393,6 @@ define_print! { } } } - debug { - match *self { - ty::Predicate::Trait(ref a) => p!(write("{:?}", a)), - ty::Predicate::Subtype(ref pair) => p!(write("{:?}", pair)), - ty::Predicate::RegionOutlives(ref pair) => p!(write("{:?}", pair)), - ty::Predicate::TypeOutlives(ref pair) => p!(write("{:?}", pair)), - ty::Predicate::Projection(ref pair) => p!(write("{:?}", pair)), - ty::Predicate::WellFormed(ty) => p!(write("WellFormed({:?})", ty)), - ty::Predicate::ObjectSafe(trait_def_id) => { - p!(write("ObjectSafe({:?})", trait_def_id)) - } - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - p!(write("ClosureKind({:?}, {:?}, {:?})", - closure_def_id, closure_substs, kind)) - } - ty::Predicate::ConstEvaluatable(def_id, substs) => { - p!(write("ConstEvaluatable({:?}, {:?})", def_id, substs)) - } - } - } } } @@ -678,12 +405,5 @@ define_print! { UnpackedKind::Const(ct) => p!(print(ct)), } } - debug { - match self.unpack() { - UnpackedKind::Lifetime(lt) => p!(write("{:?}", lt)), - UnpackedKind::Type(ty) => p!(write("{:?}", ty)), - UnpackedKind::Const(ct) => p!(write("{:?}", ct)), - } - } } } From 030cdc972930aa864fe89dd4c5125ba26ebd05ac Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 20 Jan 2019 04:56:48 +0200 Subject: [PATCH 135/157] rustc: remove obsolete hacks from ppaux, relating to normalization under HRTB. --- src/librustc/ty/print/mod.rs | 47 ++++++----- src/librustc/ty/print/pretty.rs | 56 ++++++++++++- src/librustc/ty/structural_impls.rs | 22 ----- src/librustc/util/ppaux.rs | 121 +++++++++++++++------------- 4 files changed, 142 insertions(+), 104 deletions(-) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 8c590bd783315..d1632e1e9bb54 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,6 +1,6 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::subst::{Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; @@ -16,19 +16,6 @@ pub use self::pretty::*; // FIXME(eddyb) this module uses `pub(crate)` for things used only // from `ppaux` - when that is removed, they can be re-privatized. -struct LateBoundRegionNameCollector(FxHashSet); -impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { - fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - match *r { - ty::ReLateBound(_, ty::BrNamed(_, name)) => { - self.0.insert(name); - }, - _ => {}, - } - r.super_visit_with(self) - } -} - #[derive(Default)] pub(crate) struct PrintConfig { used_region_names: Option>, @@ -67,14 +54,6 @@ impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { pub(crate) fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { ty::tls::with(|tcx| PrintCx::with(tcx, printer, f)) } - fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) - where T: TypeFoldable<'tcx> - { - let mut collector = LateBoundRegionNameCollector(Default::default()); - value.visit_with(&mut collector); - self.config.used_region_names = Some(collector.0); - self.config.region_index = 0; - } } pub trait Print<'tcx, P> { @@ -322,3 +301,27 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { ty::Float(_) => None, } } + +impl Print<'tcx, P> for ty::RegionKind { + type Output = P::Region; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.print_region(self) + } +} + +impl Print<'tcx, P> for ty::Region<'_> { + type Output = P::Region; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.print_region(self) + } +} + +impl Print<'tcx, P> for Ty<'tcx> { + type Output = P::Type; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.print_type(self) + } +} diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 6a7c48ee87940..7488b074471ff 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -205,6 +205,15 @@ pub trait PrettyPrinter: self.print_def_path(def_id, substs, iter::empty()) } + fn in_binder( + self: PrintCx<'_, '_, 'tcx, Self>, + value: &ty::Binder, + ) -> Result + where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + value.skip_binder().print(self) + } + /// Print `<...>` around what `f` prints. fn generic_delimiters<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, @@ -784,6 +793,15 @@ impl PrettyPrinter for FmtPrinter { Ok(printer) } + fn in_binder( + self: PrintCx<'_, '_, 'tcx, Self>, + value: &ty::Binder, + ) -> Result + where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + self.pretty_in_binder(value) + } + fn generic_delimiters<'gcx, 'tcx>( mut self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, @@ -1125,7 +1143,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" "), print(witness), write("]")) }, ty::GeneratorWitness(types) => { - nest!(|cx| cx.pretty_in_binder(&types)) + nest!(|cx| cx.in_binder(&types)) } ty::Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, self.tcx); @@ -1257,9 +1275,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }) }; - // NOTE(eddyb) this must be below `start_or_continue`'s definition - // as that also has a `define_scoped_cx` and that kind of shadowing - // is disallowed (name resolution thinks `scoped_cx!` is ambiguous). define_scoped_cx!(self); let old_region_index = self.config.region_index; @@ -1302,6 +1317,29 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { result } + fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) + where T: TypeFoldable<'tcx> + { + + struct LateBoundRegionNameCollector(FxHashSet); + impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + match *r { + ty::ReLateBound(_, ty::BrNamed(_, name)) => { + self.0.insert(name); + }, + _ => {}, + } + r.super_visit_with(self) + } + } + + let mut collector = LateBoundRegionNameCollector(Default::default()); + value.visit_with(&mut collector); + self.config.used_region_names = Some(collector.0); + self.config.region_index = 0; + } + fn is_name_used(&self, name: &InternedString) -> bool { match self.config.used_region_names { Some(ref names) => names.contains(name), @@ -1309,3 +1347,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } } + +impl Print<'tcx, P> for ty::Binder + where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> +{ + type Output = P; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.in_binder(self) + } +} diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 45db95e2b0f0f..dfb7e64d98bcb 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -775,28 +775,6 @@ BraceStructLiftImpl! { } } -// FIXME(eddyb) this is like what some of the macros above generate, -// except that macros *also* generate a foldable impl, which we don't -// want (with it we'd risk bypassing `fold_region` / `fold_const`). -impl<'tcx> Lift<'tcx> for ty::RegionKind { - type Lifted = ty::RegionKind; - fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - Some(self.clone()) - } -} - -impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> { - type Lifted = ty::LazyConst<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - match self { - ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)), - ty::LazyConst::Unevaluated(def_id, substs) => { - Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?)) - } - } - } -} - BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> { type Lifted = ty::Const<'tcx>; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2e11a3741369e..f8d0c8f661c77 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,7 +1,7 @@ use crate::hir; use crate::hir::def::Namespace; use crate::ty::subst::{Kind, UnpackedKind}; -use crate::ty::{self, ParamConst, Ty}; +use crate::ty::{self, ParamConst, Ty, TyCtxt}; use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print}; use crate::mir::interpret::ConstValue; @@ -10,13 +10,60 @@ use std::iter; use rustc_target::spec::abi::Abi; +pub trait LiftAndPrintToFmt<'tcx> { + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result; +} + +impl LiftAndPrintToFmt<'tcx> for T + where T: ty::Lift<'tcx>, + for<'a, 'b> >::Lifted: + Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error> +{ + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; + Ok(()) + }) + } +} + +// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. +impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { + self.print(cx)?; + Ok(()) + }) + } +} + macro_rules! define_print { - ([$($target:ty),+] $vars:tt $def:tt) => { - $(define_print!($target, $vars $def);)+ + (<$($T:ident),*> $target:ty) => { + impl<$($T),*> fmt::Display for $target + where Self: for<'a> LiftAndPrintToFmt<'a> + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f)) + } + } }; - ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { - impl Print<'tcx, P> for $target { + (<$($T:ident),*> $target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { + impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $target + where $($T: Print<'tcx, P, Output = P, Error = P::Error>),* + { type Output = P; type Error = fmt::Error; fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { @@ -29,14 +76,15 @@ macro_rules! define_print { } } - impl fmt::Display for $target { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; - Ok(()) - }) - } - } + define_print!(<$($T),*> $target); + }; + + ($target:ty) => { + define_print!(<> $target); + }; + + ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { + define_print!(<> $target, ($self, $cx) { display $disp }); }; } @@ -172,11 +220,7 @@ define_print! { } define_print! { - ty::RegionKind, (self, cx) { - display { - return cx.print_region(self); - } - } + ty::RegionKind } define_print! { @@ -215,34 +259,8 @@ define_print! { } } -// The generic impl doesn't work yet because projections are not -// normalized under HRTB. -/*impl fmt::Display for ty::Binder - where T: fmt::Display + for<'a> ty::Lift<'a>, - for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(|cx| cx.pretty_in_binder(cx.tcx.lift(self) - .expect("could not lift for printing"))) - } -}*/ - define_print! { - [ - ty::Binder<&'tcx ty::List>>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder>, - ty::Binder, ty::Region<'tcx>>>, - ty::Binder, ty::Region<'tcx>>> - ] - (self, cx) { - display { - nest!(|cx| cx.pretty_in_binder(self)) - } - } + ty::Binder } define_print! { @@ -254,11 +272,7 @@ define_print! { } define_print! { - Ty<'tcx>, (self, cx) { - display { - return cx.print_type(self); - } - } + Ty<'tcx> } define_print! { @@ -309,13 +323,8 @@ define_print! { } } -// Similar problem to `Binder`, can't define a generic impl. define_print! { - [ - ty::OutlivesPredicate, ty::Region<'tcx>>, - ty::OutlivesPredicate, ty::Region<'tcx>> - ] - (self, cx) { + ty::OutlivesPredicate, (self, cx) { display { p!(print(self.0), write(" : "), print(self.1)) } From 1a0f3a285697b6238793ce3c1353f0d2f0c28938 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 20 Jan 2019 14:00:39 +0200 Subject: [PATCH 136/157] rustc: streamline the Print/fmt::Display impls in ppaux and move them to ty::print::pretty. --- src/librustc/lib.rs | 1 - src/librustc/ty/print/mod.rs | 9 +- src/librustc/ty/print/pretty.rs | 300 +++++++++++++++++++++++ src/librustc/util/ppaux.rs | 418 -------------------------------- 4 files changed, 303 insertions(+), 425 deletions(-) delete mode 100644 src/librustc/util/ppaux.rs diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 9150417a85db6..b6677326227f4 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -135,7 +135,6 @@ pub mod ty; pub mod util { pub mod captures; pub mod common; - mod ppaux; pub mod nodemap; pub mod profiling; pub mod bug; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index d1632e1e9bb54..85786818a53e8 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -13,11 +13,8 @@ use std::ops::Deref; mod pretty; pub use self::pretty::*; -// FIXME(eddyb) this module uses `pub(crate)` for things used only -// from `ppaux` - when that is removed, they can be re-privatized. - #[derive(Default)] -pub(crate) struct PrintConfig { +struct PrintConfig { used_region_names: Option>, region_index: usize, binder_depth: usize, @@ -26,7 +23,7 @@ pub(crate) struct PrintConfig { pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, pub printer: P, - pub(crate) config: &'a mut PrintConfig, + config: &'a mut PrintConfig, } // HACK(eddyb) this is solely for `self: PrintCx`, e.g. to @@ -51,7 +48,7 @@ impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { }) } - pub(crate) fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { + pub fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { ty::tls::with(|tcx| PrintCx::with(tcx, printer, f)) } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 7488b074471ff..f1ab58bc2e247 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -9,6 +9,7 @@ use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::mir::interpret::ConstValue; use syntax::symbol::{keywords, Symbol}; +use rustc_target::spec::abi::Abi; use syntax::symbol::InternedString; use std::cell::Cell; @@ -1357,3 +1358,302 @@ impl Print<'tcx, P> for ty::Binder cx.in_binder(self) } } + +pub trait LiftAndPrintToFmt<'tcx> { + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result; +} + +impl LiftAndPrintToFmt<'tcx> for T + where T: ty::Lift<'tcx>, + for<'a, 'b> >::Lifted: + Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error> +{ + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { + cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; + Ok(()) + }) + } +} + +// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. +impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { + fn lift_and_print_to_fmt( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { + self.print(cx)?; + Ok(()) + }) + } +} + +macro_rules! forward_display_to_print { + (<$($T:ident),*> $ty:ty) => { + impl<$($T),*> fmt::Display for $ty + where Self: for<'a> LiftAndPrintToFmt<'a> + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f)) + } + } + }; + + ($ty:ty) => { + forward_display_to_print!(<> $ty); + }; +} + +macro_rules! define_print_and_forward_display { + (($self:ident, $cx:ident): <$($T:ident),*> $ty:ty $print:block) => { + impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $ty + where $($T: Print<'tcx, P, Output = P, Error = P::Error>),* + { + type Output = P; + type Error = fmt::Error; + fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + #[allow(unused_mut)] + let mut $cx = $cx; + define_scoped_cx!($cx); + let _: () = $print; + #[allow(unreachable_code)] + Ok($cx.printer) + } + } + + forward_display_to_print!(<$($T),*> $ty); + }; + + (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { + $(define_print_and_forward_display!(($self, $cx): <> $ty $print);)+ + }; +} + +forward_display_to_print!(ty::RegionKind); +forward_display_to_print!(Ty<'tcx>); +forward_display_to_print!( ty::Binder); + +define_print_and_forward_display! { + (self, cx): + + ty::OutlivesPredicate { + p!(print(self.0), write(" : "), print(self.1)) + } +} + +define_print_and_forward_display! { + (self, cx): + + &'tcx ty::List> { + // Generate the main trait ref, including associated types. + let mut first = true; + + if let Some(principal) = self.principal() { + let mut resugared_principal = false; + + // Special-case `Fn(...) -> ...` and resugar it. + let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); + if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { + let mut projections = self.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); + nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); + resugared_principal = true; + } + } + } + + if !resugared_principal { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(cx.tcx, dummy_self); + nest!(|cx| cx.print_def_path( + principal.def_id, + Some(principal.substs), + self.projection_bounds(), + )); + } + first = false; + } + + // Builtin bounds. + // FIXME(eddyb) avoid printing twice (needed to ensure + // that the auto traits are sorted *and* printed via cx). + let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { + (cx.tcx.def_path_str(did), did) + }).collect(); + + // The auto traits come ordered by `DefPathHash`. While + // `DefPathHash` is *stable* in the sense that it depends on + // neither the host nor the phase of the moon, it depends + // "pseudorandomly" on the compiler version and the target. + // + // To avoid that causing instabilities in compiletest + // output, sort the auto-traits alphabetically. + auto_traits.sort(); + + for (_, def_id) in auto_traits { + if !first { + p!(write(" + ")); + } + first = false; + + nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); + } + } + + &'tcx ty::List> { + p!(write("{{")); + let mut tys = self.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } + p!(write("}}")) + } + + ty::TypeAndMut<'tcx> { + p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), + print(self.ty)) + } + + ty::ExistentialTraitRef<'tcx> { + let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); + + let trait_ref = *ty::Binder::bind(*self) + .with_self_ty(cx.tcx, dummy_self) + .skip_binder(); + p!(print(trait_ref)) + } + + ty::FnSig<'tcx> { + if self.unsafety == hir::Unsafety::Unsafe { + p!(write("unsafe ")); + } + + if self.abi != Abi::Rust { + p!(write("extern {} ", self.abi)); + } + + p!(write("fn")); + nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + } + + ty::InferTy { + if cx.tcx.sess.verbose() { + p!(write("{:?}", self)); + return Ok(cx.printer); + } + match *self { + ty::TyVar(_) => p!(write("_")), + ty::IntVar(_) => p!(write("{}", "{integer}")), + ty::FloatVar(_) => p!(write("{}", "{float}")), + ty::FreshTy(v) => p!(write("FreshTy({})", v)), + ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)), + ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) + } + } + + ty::TraitRef<'tcx> { + nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); + } + + ConstValue<'tcx> { + match self { + ConstValue::Infer(..) => p!(write("_")), + ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), + _ => p!(write("{:?}", self)), + } + } + + ty::Const<'tcx> { + p!(write("{} : {}", self.val, self.ty)) + } + + ty::LazyConst<'tcx> { + match self { + // FIXME(const_generics) this should print at least the type. + ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), + ty::LazyConst::Evaluated(c) => p!(write("{}", c)), + } + } + + ty::ParamTy { + p!(write("{}", self.name)) + } + + ty::ParamConst { + p!(write("{}", self.name)) + } + + ty::SubtypePredicate<'tcx> { + p!(print(self.a), write(" <: "), print(self.b)) + } + + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + } + + ty::ProjectionPredicate<'tcx> { + p!(print(self.projection_ty), write(" == "), print(self.ty)) + } + + ty::ProjectionTy<'tcx> { + nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); + } + + ty::ClosureKind { + match *self { + ty::ClosureKind::Fn => p!(write("Fn")), + ty::ClosureKind::FnMut => p!(write("FnMut")), + ty::ClosureKind::FnOnce => p!(write("FnOnce")), + } + } + + ty::Predicate<'tcx> { + match *self { + ty::Predicate::Trait(ref data) => p!(print(data)), + ty::Predicate::Subtype(ref predicate) => p!(print(predicate)), + ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)), + ty::Predicate::Projection(ref predicate) => p!(print(predicate)), + ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), + ty::Predicate::ObjectSafe(trait_def_id) => { + p!(write("the trait `")); + nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty())); + p!(write("` is object-safe")) + } + ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { + p!(write("the closure `")); + nest!(|cx| cx.print_value_path(closure_def_id, None)); + p!(write("` implements the trait `{}`", kind)) + } + ty::Predicate::ConstEvaluatable(def_id, substs) => { + p!(write("the constant `")); + nest!(|cx| cx.print_value_path(def_id, Some(substs))); + p!(write("` can be evaluated")) + } + } + } + + Kind<'tcx> { + match self.unpack() { + UnpackedKind::Lifetime(lt) => p!(print(lt)), + UnpackedKind::Type(ty) => p!(print(ty)), + UnpackedKind::Const(ct) => p!(print(ct)), + } + } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs deleted file mode 100644 index f8d0c8f661c77..0000000000000 --- a/src/librustc/util/ppaux.rs +++ /dev/null @@ -1,418 +0,0 @@ -use crate::hir; -use crate::hir::def::Namespace; -use crate::ty::subst::{Kind, UnpackedKind}; -use crate::ty::{self, ParamConst, Ty, TyCtxt}; -use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print}; -use crate::mir::interpret::ConstValue; - -use std::fmt; -use std::iter; - -use rustc_target::spec::abi::Abi; - -pub trait LiftAndPrintToFmt<'tcx> { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result; -} - -impl LiftAndPrintToFmt<'tcx> for T - where T: ty::Lift<'tcx>, - for<'a, 'b> >::Lifted: - Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error> -{ - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; - Ok(()) - }) - } -} - -// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. -impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { - self.print(cx)?; - Ok(()) - }) - } -} - -macro_rules! define_print { - (<$($T:ident),*> $target:ty) => { - impl<$($T),*> fmt::Display for $target - where Self: for<'a> LiftAndPrintToFmt<'a> - { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f)) - } - } - }; - - (<$($T:ident),*> $target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { - impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $target - where $($T: Print<'tcx, P, Output = P, Error = P::Error>),* - { - type Output = P; - type Error = fmt::Error; - fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { - #[allow(unused_mut)] - let mut $cx = $cx; - define_scoped_cx!($cx); - let _: () = $disp; - #[allow(unreachable_code)] - Ok($cx.printer) - } - } - - define_print!(<$($T),*> $target); - }; - - ($target:ty) => { - define_print!(<> $target); - }; - - ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => { - define_print!(<> $target, ($self, $cx) { display $disp }); - }; -} - -macro_rules! nest { - ($closure:expr) => { - scoped_cx!() = scoped_cx!().nest($closure)? - } -} -macro_rules! print_inner { - (write ($($data:expr),+)) => { - write!(scoped_cx!().printer, $($data),+)? - }; - ($kind:ident ($data:expr)) => { - nest!(|cx| $data.$kind(cx)) - }; -} -macro_rules! p { - ($($kind:ident $data:tt),+) => { - { - $(print_inner!($kind $data));+ - } - }; -} -macro_rules! define_scoped_cx { - ($cx:ident) => { - #[allow(unused_macros)] - macro_rules! scoped_cx { - () => ($cx) - } - }; -} - -define_print! { - &'tcx ty::List>, (self, cx) { - display { - // Generate the main trait ref, including associated types. - let mut first = true; - - if let Some(principal) = self.principal() { - let mut resugared_principal = false; - - // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); - if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() { - if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { - let mut projections = self.projection_bounds(); - if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); - nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); - resugared_principal = true; - } - } - } - - if !resugared_principal { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let principal = principal.with_self_ty(cx.tcx, dummy_self); - nest!(|cx| cx.print_def_path( - principal.def_id, - Some(principal.substs), - self.projection_bounds(), - )); - } - first = false; - } - - // Builtin bounds. - // FIXME(eddyb) avoid printing twice (needed to ensure - // that the auto traits are sorted *and* printed via cx). - let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - (cx.tcx.def_path_str(did), did) - }).collect(); - - // The auto traits come ordered by `DefPathHash`. While - // `DefPathHash` is *stable* in the sense that it depends on - // neither the host nor the phase of the moon, it depends - // "pseudorandomly" on the compiler version and the target. - // - // To avoid that causing instabilities in compiletest - // output, sort the auto-traits alphabetically. - auto_traits.sort(); - - for (_, def_id) in auto_traits { - if !first { - p!(write(" + ")); - } - first = false; - - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); - } - } - } -} - -define_print! { - &'tcx ty::List>, (self, cx) { - display { - p!(write("{{")); - let mut tys = self.iter(); - if let Some(&ty) = tys.next() { - p!(print(ty)); - for &ty in tys { - p!(write(", "), print(ty)); - } - } - p!(write("}}")) - } - } -} - -define_print! { - ty::TypeAndMut<'tcx>, (self, cx) { - display { - p!( - write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), - print(self.ty)) - } - } -} - -define_print! { - ty::ExistentialTraitRef<'tcx>, (self, cx) { - display { - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - - let trait_ref = *ty::Binder::bind(*self) - .with_self_ty(cx.tcx, dummy_self) - .skip_binder(); - p!(print(trait_ref)) - } - } -} - -define_print! { - ty::RegionKind -} - -define_print! { - ty::FnSig<'tcx>, (self, cx) { - display { - if self.unsafety == hir::Unsafety::Unsafe { - p!(write("unsafe ")); - } - - if self.abi != Abi::Rust { - p!(write("extern {} ", self.abi)); - } - - p!(write("fn")); - nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); - } - } -} - -define_print! { - ty::InferTy, (self, cx) { - display { - if cx.tcx.sess.verbose() { - p!(write("{:?}", self)); - return Ok(cx.printer); - } - match *self { - ty::TyVar(_) => p!(write("_")), - ty::IntVar(_) => p!(write("{}", "{integer}")), - ty::FloatVar(_) => p!(write("{}", "{float}")), - ty::FreshTy(v) => p!(write("FreshTy({})", v)), - ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)), - ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v)) - } - } - } -} - -define_print! { - ty::Binder -} - -define_print! { - ty::TraitRef<'tcx>, (self, cx) { - display { - nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); - } - } -} - -define_print! { - Ty<'tcx> -} - -define_print! { - ConstValue<'tcx>, (self, cx) { - display { - match self { - ConstValue::Infer(..) => p!(write("_")), - ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), - _ => p!(write("{:?}", self)), - } - } - } -} - -define_print! { - ty::Const<'tcx>, (self, cx) { - display { - p!(write("{} : {}", self.val, self.ty)) - } - } -} - -define_print! { - ty::LazyConst<'tcx>, (self, cx) { - display { - match self { - // FIXME(const_generics) this should print at least the type. - ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), - ty::LazyConst::Evaluated(c) => p!(write("{}", c)), - } - } - } -} - -define_print! { - ty::ParamTy, (self, cx) { - display { - p!(write("{}", self.name)) - } - } -} - -define_print! { - ty::ParamConst, (self, cx) { - display { - p!(write("{}", self.name)) - } - } -} - -define_print! { - ty::OutlivesPredicate, (self, cx) { - display { - p!(print(self.0), write(" : "), print(self.1)) - } - } -} - -define_print! { - ty::SubtypePredicate<'tcx>, (self, cx) { - display { - p!(print(self.a), write(" <: "), print(self.b)) - } - } -} - -define_print! { - ty::TraitPredicate<'tcx>, (self, cx) { - display { - p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) - } - } -} - -define_print! { - ty::ProjectionPredicate<'tcx>, (self, cx) { - display { - p!(print(self.projection_ty), write(" == "), print(self.ty)) - } - } -} - -define_print! { - ty::ProjectionTy<'tcx>, (self, cx) { - display { - nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); - } - } -} - -define_print! { - ty::ClosureKind, (self, cx) { - display { - match *self { - ty::ClosureKind::Fn => p!(write("Fn")), - ty::ClosureKind::FnMut => p!(write("FnMut")), - ty::ClosureKind::FnOnce => p!(write("FnOnce")), - } - } - } -} - -define_print! { - ty::Predicate<'tcx>, (self, cx) { - display { - match *self { - ty::Predicate::Trait(ref data) => p!(print(data)), - ty::Predicate::Subtype(ref predicate) => p!(print(predicate)), - ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)), - ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)), - ty::Predicate::Projection(ref predicate) => p!(print(predicate)), - ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), - ty::Predicate::ObjectSafe(trait_def_id) => { - p!(write("the trait `")); - nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty())); - p!(write("` is object-safe")) - } - ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!(write("the closure `")); - nest!(|cx| cx.print_value_path(closure_def_id, None)); - p!(write("` implements the trait `{}`", kind)) - } - ty::Predicate::ConstEvaluatable(def_id, substs) => { - p!(write("the constant `")); - nest!(|cx| cx.print_value_path(def_id, Some(substs))); - p!(write("` can be evaluated")) - } - } - } - } -} - -define_print! { - Kind<'tcx>, (self, cx) { - display { - match self.unpack() { - UnpackedKind::Lifetime(lt) => p!(print(lt)), - UnpackedKind::Type(ty) => p!(print(ty)), - UnpackedKind::Const(ct) => p!(print(ct)), - } - } - } -} From 381fa7aa18d0440d122c476bdbd074281a93b6a9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 20 Jan 2019 19:46:47 +0200 Subject: [PATCH 137/157] rustc: move ty::print::PrintConfig's fields to FmtPrinter. --- src/librustc/infer/error_reporting/mod.rs | 5 +- .../infer/error_reporting/need_type_info.rs | 4 +- .../nice_region_error/placeholder_error.rs | 6 +- src/librustc/ty/print/mod.rs | 48 ++- src/librustc/ty/print/pretty.rs | 279 +++++++++--------- src/librustc_codegen_utils/symbol_names.rs | 19 +- .../borrow_check/error_reporting.rs | 8 +- src/librustdoc/clean/mod.rs | 6 +- 8 files changed, 185 insertions(+), 190 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 73a8721bdeb2e..a7ce53e9876ac 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -526,9 +526,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { - PrintCx::with(self.tcx, AbsolutePathPrinter, |cx| { - cx.print_def_path(def_id, None, iter::empty()) - }) + PrintCx::new(self.tcx, AbsolutePathPrinter) + .print_def_path(def_id, None, iter::empty()) }; // We compare strings because DefPath can be different diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 2fabbbeadbd9c..f649309004bfc 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -84,9 +84,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(highlight) = highlight { printer.region_highlight_mode = highlight; } - let _ = ty::print::PrintCx::with(self.tcx, printer, |cx| { - ty.print(cx) - }); + let _ = ty.print(ty::print::PrintCx::new(self.tcx, printer)); s } diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 39ab244dae1c5..fd01ed85ef721 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -347,10 +347,8 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { let mut printer = ty::print::FmtPrinter::new(f, Namespace::TypeNS); printer.region_highlight_mode = self.highlight; - ty::print::PrintCx::with(self.tcx, printer, |cx| { - self.value.print(cx)?; - Ok(()) - }) + self.value.print(ty::print::PrintCx::new(self.tcx, printer))?; + Ok(()) } } diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 85786818a53e8..aac76025951fb 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -4,52 +4,50 @@ use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::subst::{Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; -use syntax::symbol::InternedString; use std::iter; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. mod pretty; pub use self::pretty::*; -#[derive(Default)] -struct PrintConfig { - used_region_names: Option>, - region_index: usize, - binder_depth: usize, -} - pub struct PrintCx<'a, 'gcx, 'tcx, P> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, - pub printer: P, - config: &'a mut PrintConfig, + inner: P, } -// HACK(eddyb) this is solely for `self: PrintCx`, e.g. to -// implement traits on the printer and call the methods on the context. impl

Deref for PrintCx<'_, '_, '_, P> { type Target = P; fn deref(&self) -> &P { - &self.printer + &self.inner + } +} + +impl

DerefMut for PrintCx<'_, '_, '_, P> { + fn deref_mut(&mut self) -> &mut P { + &mut self.inner } } impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { - pub fn with( - tcx: TyCtxt<'a, 'gcx, 'tcx>, - printer: P, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, P>) -> R, - ) -> R { - f(PrintCx { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, inner: P) -> Self { + PrintCx { tcx, - printer, - config: &mut PrintConfig::default(), - }) + inner, + } + } + + pub fn with_tls_tcx(inner: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { + ty::tls::with(|tcx| f(PrintCx::new(tcx, inner))) + } + + pub fn into_inner(self) -> P { + self.inner } - pub fn with_tls_tcx(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { - ty::tls::with(|tcx| PrintCx::with(tcx, printer, f)) + pub fn ok(self) -> Result { + Ok(self.into_inner()) } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index f1ab58bc2e247..1f609dbc6e56f 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -15,6 +15,7 @@ use syntax::symbol::InternedString; use std::cell::Cell; use std::fmt::{self, Write as _}; use std::iter; +use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. use super::*; @@ -26,7 +27,7 @@ macro_rules! nest { } macro_rules! print_inner { (write ($($data:expr),+)) => { - write!(scoped_cx!().printer, $($data),+)? + write!(scoped_cx!(), $($data),+)? }; ($kind:ident ($data:expr)) => { nest!(|cx| $data.$kind(cx)) @@ -185,16 +186,7 @@ pub trait PrettyPrinter: self: PrintCx<'a, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result, E> { - let printer = f(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - })?; - Ok(PrintCx { - tcx: self.tcx, - printer, - config: self.config, - }) + Ok(PrintCx::new(self.tcx, f(self)?)) } /// Like `print_def_path` but for value paths. @@ -243,6 +235,12 @@ pub trait PrettyPrinter: ) -> bool; } +impl fmt::Write for PrintCx<'_, '_, '_, P> { + fn write_str(&mut self, s: &str) -> fmt::Result { + (**self).write_str(s) + } +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always // (but also some things just print a `DefId` generally so maybe we need this?) @@ -268,31 +266,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let ns = self.guess_def_namespace(def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); - let _ = PrintCx::with(self, FmtPrinter::new(&mut s, ns), |cx| { - cx.print_def_path(def_id, None, iter::empty()) - }); + let _ = PrintCx::new(self, FmtPrinter::new(&mut s, ns)) + .print_def_path(def_id, None, iter::empty()); s } } -pub struct FmtPrinter { - fmt: F, - empty: bool, - in_value: bool, - pub region_highlight_mode: RegionHighlightMode, -} - -impl FmtPrinter { - pub fn new(fmt: F, ns: Namespace) -> Self { - FmtPrinter { - fmt, - empty: true, - in_value: ns == Namespace::ValueNS, - region_highlight_mode: RegionHighlightMode::default(), - } - } -} - impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is @@ -346,7 +325,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } if def_id.is_local() { - return Ok((self.printer, false)); + return self.ok().map(|path| (path, false)); } let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); @@ -366,7 +345,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let visible_parent = match visible_parent_map.get(&def_id).cloned() { Some(parent) => parent, - None => return Ok((self.printer, false)), + None => return self.ok().map(|path| (path, false)), }; // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether // the entire path will succeed or not. To support printers that do not @@ -374,12 +353,12 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // need to be built, before starting to print anything. let mut prefix_success = false; nest!(|cx| { - let (printer, success) = cx.try_print_visible_def_path(visible_parent)?; + let (path, success) = cx.try_print_visible_def_path(visible_parent)?; prefix_success = success; - Ok(printer) + Ok(path) }); if !prefix_success { - return Ok((self.printer, false)); + return self.ok().map(|path| (path, false)); }; let actual_parent = self.tcx.parent(def_id); debug!( @@ -445,7 +424,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }, }; debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok((self.path_append(|cx| Ok(cx.printer), &symbol)?, true)) + Ok((self.path_append(|cx| cx.ok(), &symbol)?, true)) } pub fn pretty_path_qualified( @@ -475,7 +454,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { if let Some(trait_ref) = trait_ref { p!(write(" as "), print(trait_ref)); } - Ok(cx.printer) + cx.ok() }) } @@ -498,7 +477,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(print(self_ty)); - Ok(cx.printer) + cx.ok() }) } @@ -556,7 +535,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let projection0 = projections.next(); if arg0.is_none() && projection0.is_none() { - return Ok(self.printer); + return self.ok(); } self.generic_delimiters(|mut cx| { @@ -568,7 +547,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { empty = false; Ok(()) } else { - write!(cx.printer, ", ") + write!(cx, ", ") } }; @@ -598,11 +577,54 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { print(projection.ty)); } - Ok(cx.printer) + cx.ok() }) } } +// HACK(eddyb) boxed to avoid moving around a large struct by-value. +pub struct FmtPrinter(Box>); + +pub struct FmtPrinterData { + fmt: F, + + empty: bool, + in_value: bool, + + used_region_names: FxHashSet, + region_index: usize, + binder_depth: usize, + + pub region_highlight_mode: RegionHighlightMode, +} + +impl Deref for FmtPrinter { + type Target = FmtPrinterData; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for FmtPrinter { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl FmtPrinter { + pub fn new(fmt: F, ns: Namespace) -> Self { + FmtPrinter(Box::new(FmtPrinterData { + fmt, + empty: true, + in_value: ns == Namespace::ValueNS, + used_region_names: Default::default(), + region_index: 0, + binder_depth: 0, + region_highlight_mode: RegionHighlightMode::default(), + })) + } +} + impl fmt::Write for FmtPrinter { fn write_str(&mut self, s: &str) -> fmt::Result { self.empty &= s.is_empty(); @@ -629,17 +651,17 @@ impl Printer for FmtPrinter { if generics.as_ref().and_then(|g| g.parent).is_none() { let mut visible_path_success = false; self = self.nest(|cx| { - let (printer, success) = cx.try_print_visible_def_path(def_id)?; + let (path, success) = cx.try_print_visible_def_path(def_id)?; visible_path_success = success; - Ok(printer) + Ok(path) })?; if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; - self.path_generic_args(|cx| Ok(cx.printer), params, substs, projections) + self.path_generic_args(|cx| cx.ok(), params, substs, projections) } else { - Ok(self.printer) + self.ok() }; } } @@ -693,14 +715,13 @@ impl Printer for FmtPrinter { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - write!(self.printer, "{}", keywords::Crate.name())?; + write!(self, "{}", keywords::Crate.name())?; } } - Ok(self.printer) } else { - write!(self.printer, "{}", self.tcx.crate_name(cnum))?; - Ok(self.printer) + write!(self, "{}", self.tcx.crate_name(cnum))?; } + self.ok() } fn path_qualified( self: PrintCx<'_, '_, 'tcx, Self>, @@ -719,15 +740,15 @@ impl Printer for FmtPrinter { trait_ref: Option>, ) -> Result { self.pretty_path_append_impl(|cx| { - let mut printer = print_prefix(cx)?; + let mut path = print_prefix(cx)?; // HACK(eddyb) this accounts for `generic_delimiters` // printing `::<` instead of `<` if `in_value` is set. - if !printer.empty && !printer.in_value { - write!(printer, "::")?; + if !path.empty && !path.in_value { + write!(path, "::")?; } - Ok(printer) + Ok(path) }, self_ty, trait_ref) } fn path_append<'gcx, 'tcx>( @@ -737,18 +758,18 @@ impl Printer for FmtPrinter { ) -> Result, text: &str, ) -> Result { - let mut printer = print_prefix(self)?; + let mut path = print_prefix(self)?; // FIXME(eddyb) `text` should never be empty, but it // currently is for `extern { ... }` "foreign modules". if !text.is_empty() { - if !printer.empty { - write!(printer, "::")?; + if !path.empty { + write!(path, "::")?; } - write!(printer, "{}", text)?; + write!(path, "{}", text)?; } - Ok(printer) + Ok(path) } fn path_generic_args<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, @@ -768,18 +789,11 @@ impl PrettyPrinter for FmtPrinter { mut self: PrintCx<'a, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result, E> { - let was_empty = std::mem::replace(&mut self.printer.empty, true); - let mut printer = f(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - })?; - printer.empty &= was_empty; - Ok(PrintCx { - tcx: self.tcx, - printer, - config: self.config, - }) + let tcx = self.tcx; + let was_empty = std::mem::replace(&mut self.empty, true); + let mut inner = f(self)?; + inner.empty &= was_empty; + Ok(PrintCx::new(tcx, inner)) } fn print_value_path( @@ -787,11 +801,11 @@ impl PrettyPrinter for FmtPrinter { def_id: DefId, substs: Option>, ) -> Result { - let was_in_value = std::mem::replace(&mut self.printer.in_value, true); - let mut printer = self.print_def_path(def_id, substs, iter::empty())?; - printer.in_value = was_in_value; + let was_in_value = std::mem::replace(&mut self.in_value, true); + let mut path = self.print_def_path(def_id, substs, iter::empty())?; + path.in_value = was_in_value; - Ok(printer) + Ok(path) } fn in_binder( @@ -807,18 +821,18 @@ impl PrettyPrinter for FmtPrinter { mut self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result { - if !self.printer.empty && self.printer.in_value { - write!(self.printer, "::<")?; + if !self.empty && self.in_value { + write!(self, "::<")?; } else { - write!(self.printer, "<")?; + write!(self, "<")?; } - let was_in_value = std::mem::replace(&mut self.printer.in_value, false); - let mut printer = f(self)?; - printer.in_value = was_in_value; + let was_in_value = std::mem::replace(&mut self.in_value, false); + let mut inner = f(self)?; + inner.in_value = was_in_value; - write!(printer, ">")?; - Ok(printer) + write!(inner, ">")?; + Ok(inner) } fn always_print_region_in_paths( @@ -832,7 +846,7 @@ impl PrettyPrinter for FmtPrinter { self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, ) -> bool { - let highlight = self.printer.region_highlight_mode; + let highlight = self.region_highlight_mode; if highlight.region_highlighted(region).is_some() { return true; } @@ -889,15 +903,15 @@ impl FmtPrinter { define_scoped_cx!(self); // Watch out for region highlights. - let highlight = self.printer.region_highlight_mode; + let highlight = self.region_highlight_mode; if let Some(n) = highlight.region_highlighted(region) { p!(write("'{}", n)); - return Ok(self.printer); + return self.ok(); } if self.tcx.sess.verbose() { p!(write("{:?}", region)); - return Ok(self.printer); + return self.ok(); } let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; @@ -918,7 +932,7 @@ impl FmtPrinter { if let ty::BrNamed(_, name) = br { if name != "" && name != "'_" { p!(write("{}", name)); - return Ok(self.printer); + return self.ok(); } } @@ -958,7 +972,7 @@ impl FmtPrinter { ty::ReClosureBound(vid) => p!(write("{:?}", vid)), } - Ok(self.printer) + self.ok() } } @@ -1056,7 +1070,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // FIXME(eddyb) print this with `print_def_path`. if self.tcx.sess.verbose() { p!(write("Opaque({:?}, {:?})", def_id, substs)); - return Ok(self.printer); + return self.ok(); } let def_key = self.tcx.def_key(def_id); @@ -1072,7 +1086,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(write(">")); } - return Ok(self.printer); + return self.ok(); } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. @@ -1216,7 +1230,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - Ok(self.printer) + self.ok() } pub fn pretty_fn_sig( @@ -1243,11 +1257,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" -> "), print(output)); } - Ok(self.printer) + self.ok() } +} - pub fn pretty_in_binder(mut self, value: &ty::Binder) -> Result - where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx> +// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, +// `region_index` and `used_region_names`. +impl FmtPrinter { + pub fn pretty_in_binder( + mut self: PrintCx<'_, '_, 'tcx, Self>, + value: &ty::Binder, + ) -> Result + where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -1262,13 +1283,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // clearly differentiate between named and unnamed regions in // the output. We'll probably want to tweak this over time to // decide just how much information to give. - if self.config.binder_depth == 0 { + if self.binder_depth == 0 { self.prepare_late_bound_region_info(value); } let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - write!(cx.printer, "{}", if empty { + write!(cx, "{}", if empty { empty = false; start } else { @@ -1278,13 +1299,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { define_scoped_cx!(self); - let old_region_index = self.config.region_index; + let old_region_index = self.region_index; let mut region_index = old_region_index; let new_value = self.tcx.replace_late_bound_regions(value, |br| { let _ = start_or_continue(&mut self, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { - let _ = write!(self.printer, "{}", name); + let _ = write!(self, "{}", name); br } ty::BrAnon(_) | @@ -1293,11 +1314,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let name = loop { let name = name_by_region_index(region_index); region_index += 1; - if !self.is_name_used(&name) { + if !self.used_region_names.contains(&name) { break name; } }; - let _ = write!(self.printer, "{}", name); + let _ = write!(self, "{}", name); ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) } }; @@ -1305,25 +1326,20 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }).0; start_or_continue(&mut self, "", "> ")?; - // Push current state to gcx, and restore after writing new_value. - self.config.binder_depth += 1; - self.config.region_index = region_index; - let result = new_value.print(PrintCx { - tcx: self.tcx, - printer: self.printer, - config: self.config, - }); - self.config.region_index = old_region_index; - self.config.binder_depth -= 1; - result + self.binder_depth += 1; + self.region_index = region_index; + let mut inner = new_value.print(self)?; + inner.region_index = old_region_index; + inner.binder_depth -= 1; + Ok(inner) } fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) - where T: TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { - struct LateBoundRegionNameCollector(FxHashSet); - impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { + struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); + impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReLateBound(_, ty::BrNamed(_, name)) => { @@ -1335,17 +1351,10 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - let mut collector = LateBoundRegionNameCollector(Default::default()); + self.used_region_names.clear(); + let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names); value.visit_with(&mut collector); - self.config.used_region_names = Some(collector.0); - self.config.region_index = 0; - } - - fn is_name_used(&self, name: &InternedString) -> bool { - match self.config.used_region_names { - Some(ref names) => names.contains(name), - None => false, - } + self.region_index = 0; } } @@ -1377,10 +1386,10 @@ impl LiftAndPrintToFmt<'tcx> for T tcx: TyCtxt<'_, '_, 'tcx>, f: &mut fmt::Formatter<'_>, ) -> fmt::Result { - PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.tcx.lift(self).expect("could not lift for printing").print(cx)?; - Ok(()) - }) + tcx.lift(self) + .expect("could not lift for printing") + .print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; + Ok(()) } } @@ -1391,10 +1400,8 @@ impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { tcx: TyCtxt<'_, '_, 'tcx>, f: &mut fmt::Formatter<'_>, ) -> fmt::Result { - PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| { - self.print(cx)?; - Ok(()) - }) + self.print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; + Ok(()) } } @@ -1427,7 +1434,7 @@ macro_rules! define_print_and_forward_display { define_scoped_cx!($cx); let _: () = $print; #[allow(unreachable_code)] - Ok($cx.printer) + $cx.ok() } } @@ -1555,7 +1562,7 @@ define_print_and_forward_display! { ty::InferTy { if cx.tcx.sess.verbose() { p!(write("{:?}", self)); - return Ok(cx.printer); + return cx.ok(); } match *self { ty::TyVar(_) => p!(write("_")), diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index a17a554480eb8..b7e69f64f5ae3 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -224,11 +224,10 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - PrintCx::with(tcx, SymbolPath::new(tcx), |cx| { - cx.print_def_path(def_id, None, iter::empty()) - .unwrap() - .into_interned() - }) + PrintCx::new(tcx, SymbolPath::new(tcx)) + .print_def_path(def_id, None, iter::empty()) + .unwrap() + .into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -415,7 +414,7 @@ impl Printer for SymbolPath { self: PrintCx<'_, '_, '_, Self>, _region: ty::Region<'_>, ) -> Result { - Ok(self.printer) + self.ok() } fn print_type( @@ -440,8 +439,8 @@ impl Printer for SymbolPath { mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { - self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?; - Ok(self.printer) + self.write_str(&self.tcx.original_crate_name(cnum).as_str())?; + self.ok() } fn path_qualified( self: PrintCx<'_, '_, 'tcx, Self>, @@ -524,10 +523,10 @@ impl PrettyPrinter for SymbolPath { mut self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result { - write!(self.printer, "<")?; + write!(self, "<")?; let kept_within_component = - mem::replace(&mut self.printer.keep_within_component, true); + mem::replace(&mut self.keep_within_component, true); let mut path = f(self)?; path.keep_within_component = kept_within_component; diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 7a92a507ec160..d7dd0313e9487 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -2341,9 +2341,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => {} } - let _ = ty::print::PrintCx::with(self.infcx.tcx, printer, |cx| { - ty.print(cx) - }); + let _ = ty.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); s } @@ -2368,9 +2366,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => bug!("ty for annotation of borrow region is not a reference"), }; - let _ = ty::print::PrintCx::with(self.infcx.tcx, printer, |cx| { - region.print(cx) - }); + let _ = region.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); s } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 02b8291369d9d..c486628a4f546 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4312,9 +4312,9 @@ where F: Fn(DefId) -> Def { } } - let names = PrintCx::with(tcx, AbsolutePathPrinter, |cx| { - cx.print_def_path(def_id, None, iter::empty()).unwrap() - }); + let names = PrintCx::new(tcx, AbsolutePathPrinter) + .print_def_path(def_id, None, iter::empty()) + .unwrap(); hir::Path { span: DUMMY_SP, From 72690d24f02543f5a3c77a8506da48bb32fdc466 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 23 Jan 2019 18:39:05 +0200 Subject: [PATCH 138/157] rustc: always hide defaulted generic args, even in verbose mode. --- src/librustc/ty/print/mod.rs | 31 +++++++++++++++++++++---- src/librustc/ty/print/pretty.rs | 22 +----------------- src/test/ui/substs-ppaux.rs | 2 +- src/test/ui/substs-ppaux.verbose.stderr | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index aac76025951fb..af6f8ba72f078 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,7 +1,7 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; -use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::subst::{Kind, Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; @@ -129,7 +129,7 @@ pub trait Printer: Sized { ) -> Result; } -impl PrintCx<'a, 'gcx, 'tcx, P> { +impl PrintCx<'_, 'gcx, 'tcx, P> { pub fn default_print_def_path( self, def_id: DefId, @@ -197,8 +197,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { }; if let (Some(generics), Some(substs)) = (generics, substs) { - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; + let params = self.generic_params_to_print(generics, substs); self.path_generic_args(print_path, params, substs, projections) } else { print_path(self) @@ -207,6 +206,30 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } } + pub fn generic_params_to_print( + &self, + generics: &'a ty::Generics, + substs: SubstsRef<'tcx>, + ) -> &'a [ty::GenericParamDef] { + // Don't print args for `Self` parameters (of traits). + let has_own_self = generics.has_self && generics.parent_count == 0; + let params = &generics.params[has_own_self as usize..]; + + // Don't print args that are the defaults of their respective parameters. + let num_supplied_defaults = params.iter().rev().take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default && substs[param.index as usize] == Kind::from( + self.tcx.type_of(param.def_id).subst(self.tcx, substs) + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) + } + }).count(); + ¶ms[..params.len() - num_supplied_defaults] + } + fn default_print_impl_path( self, impl_def_id: DefId, diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 1f609dbc6e56f..7358dd1932f47 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -502,25 +502,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { _ => false, } }); - - // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = if self.tcx.sess.verbose() { - 0 - } else { - params.iter().rev().take_while(|param| { - match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default && substs[param.index as usize] == Kind::from( - self.tcx.type_of(param.def_id).subst(self.tcx, substs) - ) - } - ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) - } - }).count() - }; - - let params = ¶ms[..params.len() - num_supplied_defaults]; let mut args = params.iter().map(|param| { substs[param.index as usize] }).filter(|arg| { @@ -657,8 +638,7 @@ impl Printer for FmtPrinter { })?; if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; + let params = self.generic_params_to_print(generics, substs); self.path_generic_args(|cx| cx.ok(), params, substs, projections) } else { self.ok() diff --git a/src/test/ui/substs-ppaux.rs b/src/test/ui/substs-ppaux.rs index 7ad7ccb54448f..129ebd43594ce 100644 --- a/src/test/ui/substs-ppaux.rs +++ b/src/test/ui/substs-ppaux.rs @@ -25,7 +25,7 @@ fn foo<'z>() where &'z (): Sized { let x: () = >::bar::<'static, char>; //[verbose]~^ ERROR mismatched types //[verbose]~| expected type `()` - //[verbose]~| found type `fn() {>::bar::}` + //[verbose]~| found type `fn() {>::bar::}` //[normal]~^^^^ ERROR mismatched types //[normal]~| expected type `()` //[normal]~| found type `fn() {>::bar::<'static, char>}` diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr index 9d8a555dffe16..86936475f8c14 100644 --- a/src/test/ui/substs-ppaux.verbose.stderr +++ b/src/test/ui/substs-ppaux.verbose.stderr @@ -14,7 +14,7 @@ LL | let x: () = >::bar::<'static, char>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item | = note: expected type `()` - found type `fn() {>::bar::}` + found type `fn() {>::bar::}` error[E0308]: mismatched types --> $DIR/substs-ppaux.rs:33:17 From 4deaa69b429442c0e25a7828cfd63d7be78772d8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 23 Jan 2019 19:36:39 +0200 Subject: [PATCH 139/157] rustc: print elided regions as '_ instead of nothing, and use a separate check when optional. --- src/librustc/infer/error_reporting/mod.rs | 10 +++- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/print/pretty.rs | 56 +++++++++---------- src/librustc_codegen_utils/symbol_names.rs | 2 +- .../ui/issues/issue-20831-debruijn.stderr | 4 +- .../regions/regions-addr-of-upvar-self.stderr | 2 +- ...ons-return-ref-to-upvar-issue-17403.stderr | 2 +- 8 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a7ce53e9876ac..14d9f9deb50ed 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -826,11 +826,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { mutbl: hir::Mutability, s: &mut DiagnosticStyledString, ) { - let r = &r.to_string(); + let mut r = r.to_string(); + if r == "'_" { + r.clear(); + } else { + r.push(' '); + } s.push_highlighted(format!( - "&{}{}{}", + "&{}{}", r, - if r == "" { "" } else { " " }, if mutbl == hir::MutMutable { "mut " } else { "" } )); s.push_normal(ty.to_string()); diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 69d5492c0f450..c576586fcad8e 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< w.push('<'); w.push_str(&substs.iter() .map(|k| k.to_string()) - .filter(|k| !k.is_empty()) + .filter(|k| k != "'_") .collect::>().join(", ")); w.push('>'); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 4a3e814cf476d..fa3c76a817a4f 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -190,7 +190,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { let tymut_string = tymut.to_string(); if tymut_string == "_" || //unknown type name, tymut_string.len() > 10 || //name longer than saying "reference", - region.to_string() != "" //... or a complex type + region.to_string() != "'_" //... or a complex type { format!("{}reference", match mutbl { hir::Mutability::MutMutable => "mutable ", diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 7358dd1932f47..d4a539e3eed5c 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -222,14 +222,10 @@ pub trait PrettyPrinter: false } - // HACK(eddyb) Trying to print a lifetime might not print anything, which - // may need special handling in the caller (of `ty::RegionKind::print`). - // To avoid printing to a temporary string (which isn't even supported), - // the `print_region_outputs_anything` method can instead be used to - // determine this, ahead of time. - // - // NB: this must be kept in sync with the implementation of `print_region`. - fn print_region_outputs_anything( + /// Return `true` if the region should be printed in + /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. + /// This is typically the case for all non-`'_` regions. + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, ) -> bool; @@ -497,7 +493,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { match substs[param.index as usize].unpack() { UnpackedKind::Lifetime(r) => { self.always_print_region_in_paths(r) || - self.print_region_outputs_anything(r) + self.region_should_not_be_omitted(r) } _ => false, } @@ -535,19 +531,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { for arg in arg0.into_iter().chain(args) { maybe_comma(&mut cx)?; - if let UnpackedKind::Lifetime(region) = arg.unpack() { - if !cx.print_region_outputs_anything(region) { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - p!(write("'_")); - - continue; - } - } - p!(print(arg)); } @@ -822,7 +805,7 @@ impl PrettyPrinter for FmtPrinter { *region != ty::ReErased } - fn print_region_outputs_anything( + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, ) -> bool { @@ -902,8 +885,9 @@ impl FmtPrinter { // `explain_region()` or `note_and_explain_region()`. match *region { ty::ReEarlyBound(ref data) => { - if data.name != "'_" { + if data.name != "" { p!(write("{}", data.name)); + return self.ok(); } } ty::ReLateBound(_, br) | @@ -919,6 +903,7 @@ impl FmtPrinter { if let Some((region, counter)) = highlight.highlight_bound_region { if br == region { p!(write("'{}", counter)); + return self.ok(); } } } @@ -938,20 +923,33 @@ impl FmtPrinter { first_statement_index.index() )), } + return self.ok(); } ty::ReVar(region_vid) if identify_regions => { p!(write("{:?}", region_vid)); + return self.ok(); } ty::ReVar(_) => {} ty::ReScope(_) | ty::ReErased => {} - ty::ReStatic => p!(write("'static")), - ty::ReEmpty => p!(write("'")), + ty::ReStatic => { + p!(write("'static")); + return self.ok(); + } + ty::ReEmpty => { + p!(write("'")); + return self.ok(); + } // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => p!(write("{:?}", vid)), + ty::ReClosureBound(vid) => { + p!(write("{:?}", vid)); + return self.ok(); + } } + p!(write("'_")); + self.ok() } } @@ -978,7 +976,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Ref(r, ty, mutbl) => { p!(write("&")); - if self.print_region_outputs_anything(r) { + if self.region_should_not_be_omitted(r) { p!(print(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) @@ -1027,7 +1025,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); } ty::Dynamic(data, r) => { - let print_r = self.print_region_outputs_anything(r); + let print_r = self.region_should_not_be_omitted(r); if print_r { p!(write("(")); } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index b7e69f64f5ae3..1edb5dfe2b88f 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -512,7 +512,7 @@ impl Printer for SymbolPath { } impl PrettyPrinter for SymbolPath { - fn print_region_outputs_anything( + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, _region: ty::Region<'_>, ) -> bool { diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index b2a05551837ce..e20869a6f3a75 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -11,7 +11,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 | @@ -42,7 +42,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the lifetime 'a as defined on the impl at 26:6... --> $DIR/issue-20831-debruijn.rs:26:6 | diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr index 01b2631a53717..ac5e5e9aabc5b 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 9:18... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18... --> $DIR/regions-addr-of-upvar-self.rs:9:18 | LL | let _f = || { diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr index 9cf0b0ffabde5..be441bc48082e 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let mut f = || &mut x; | ^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 7:21... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21... --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21 | LL | let mut f = || &mut x; From ffa00d4628aac6503d7ef04b9f37a52ed6104dfc Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 24 Jan 2019 19:52:43 +0200 Subject: [PATCH 140/157] rustc: make `pretty_path_generic_args`' task as simple as possible. --- src/librustc/infer/error_reporting/mod.rs | 5 +- src/librustc/ty/print/mod.rs | 17 +-- src/librustc/ty/print/pretty.rs | 118 +++++++++------------ src/librustc_codegen_utils/symbol_names.rs | 13 ++- src/librustdoc/clean/mod.rs | 5 +- 5 files changed, 70 insertions(+), 88 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 14d9f9deb50ed..06495510ede47 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -446,7 +446,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) { use hir::def_id::CrateNum; use ty::print::{PrintCx, Printer}; - use ty::subst::SubstsRef; + use ty::subst::Kind; struct AbsolutePathPrinter; @@ -513,8 +513,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _params: &[ty::GenericParamDef], - _substs: SubstsRef<'tcx>, + _args: impl Iterator> + Clone, _projections: impl Iterator>, ) -> Result { print_prefix(self) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index af6f8ba72f078..d89bd84a34942 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -123,8 +123,7 @@ pub trait Printer: Sized { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, + args: impl Iterator> + Clone, projections: impl Iterator>, ) -> Result; } @@ -197,8 +196,8 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { }; if let (Some(generics), Some(substs)) = (generics, substs) { - let params = self.generic_params_to_print(generics, substs); - self.path_generic_args(print_path, params, substs, projections) + let args = self.generic_args_to_print(generics, substs); + self.path_generic_args(print_path, args, projections) } else { print_path(self) } @@ -206,11 +205,11 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { } } - pub fn generic_params_to_print( + pub fn generic_args_to_print( &self, - generics: &'a ty::Generics, + generics: &'tcx ty::Generics, substs: SubstsRef<'tcx>, - ) -> &'a [ty::GenericParamDef] { + ) -> impl Iterator> + Clone { // Don't print args for `Self` parameters (of traits). let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; @@ -227,7 +226,9 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) } }).count(); - ¶ms[..params.len() - num_supplied_defaults] + params[..params.len() - num_supplied_defaults].iter().map(move |param| { + substs[param.index as usize] + }) } fn default_print_impl_path( diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index d4a539e3eed5c..a1e157685c9e2 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -207,21 +207,30 @@ pub trait PrettyPrinter: value.skip_binder().print(self) } + /// Print comma-separated elements. + fn comma_sep( + mut self: PrintCx<'_, '_, 'tcx, Self>, + mut elems: impl Iterator, + comma: &str, + ) -> Result + where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + { + if let Some(first) = elems.next() { + self = self.nest(|cx| first.print(cx))?; + for elem in elems { + self.write_str(comma)?; + self = self.nest(|cx| elem.print(cx))?; + } + } + self.ok() + } + /// Print `<...>` around what `f` prints. fn generic_delimiters<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result; - /// Return `true` if the region should be printed in path generic args - /// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`. - fn always_print_region_in_paths( - self: &PrintCx<'_, '_, '_, Self>, - _region: ty::Region<'_>, - ) -> bool { - false - } - /// Return `true` if the region should be printed in /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. /// This is typically the case for all non-`'_` regions. @@ -482,66 +491,25 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, P>, ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, - projections: impl Iterator>, + mut args: impl Iterator>, + mut projections: impl Iterator>, ) -> Result { self = self.nest(print_prefix)?; - // Don't print `'_` if there's no printed region. - let print_regions = params.iter().any(|param| { - match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(r) => { - self.always_print_region_in_paths(r) || - self.region_should_not_be_omitted(r) - } - _ => false, - } - }); - let mut args = params.iter().map(|param| { - substs[param.index as usize] - }).filter(|arg| { - match arg.unpack() { - UnpackedKind::Lifetime(_) => print_regions, - _ => true, - } - }); let arg0 = args.next(); - - let mut projections = projections; let projection0 = projections.next(); - if arg0.is_none() && projection0.is_none() { return self.ok(); } + let args = arg0.into_iter().chain(args); + let projections = projection0.into_iter().chain(projections); self.generic_delimiters(|mut cx| { - define_scoped_cx!(cx); - - let mut empty = true; - let mut maybe_comma = |cx: &mut Self| { - if empty { - empty = false; - Ok(()) - } else { - write!(cx, ", ") - } - }; - - for arg in arg0.into_iter().chain(args) { - maybe_comma(&mut cx)?; - - p!(print(arg)); + cx = cx.nest(|cx| cx.comma_sep(args, ", "))?; + if arg0.is_some() && projection0.is_some() { + write!(cx, ", ")?; } - - for projection in projection0.into_iter().chain(projections) { - maybe_comma(&mut cx)?; - - p!(write("{}=", cx.tcx.associated_item(projection.item_def_id).ident), - print(projection.ty)); - } - - cx.ok() + cx.comma_sep(projections, ", ") }) } } @@ -621,8 +589,8 @@ impl Printer for FmtPrinter { })?; if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { - let params = self.generic_params_to_print(generics, substs); - self.path_generic_args(|cx| cx.ok(), params, substs, projections) + let args = self.generic_args_to_print(generics, substs); + self.path_generic_args(|cx| cx.ok(), args, projections) } else { self.ok() }; @@ -739,11 +707,23 @@ impl Printer for FmtPrinter { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, + args: impl Iterator> + Clone, projections: impl Iterator>, ) -> Result { - self.pretty_path_generic_args(print_prefix, params, substs, projections) + // Don't print `'_` if there's no unerased regions. + let print_regions = args.clone().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let args = args.filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + self.pretty_path_generic_args(print_prefix, args, projections) } } @@ -798,13 +778,6 @@ impl PrettyPrinter for FmtPrinter { Ok(inner) } - fn always_print_region_in_paths( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool { - *region != ty::ReErased - } - fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, @@ -1498,6 +1471,11 @@ define_print_and_forward_display! { } } + ty::ExistentialProjection<'tcx> { + let name = cx.tcx.associated_item(self.item_def_id).ident; + p!(write("{}=", name), print(self.ty)) + } + &'tcx ty::List> { p!(write("{{")); let mut tys = self.iter(); diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 1edb5dfe2b88f..93e7e495d4ede 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -94,7 +94,7 @@ use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; use rustc::ty::print::{PrettyPrinter, PrintCx, Printer}; use rustc::ty::query::Providers; -use rustc::ty::subst::SubstsRef; +use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::record_time; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -503,11 +503,16 @@ impl Printer for SymbolPath { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - params: &[ty::GenericParamDef], - substs: SubstsRef<'tcx>, + args: impl Iterator> + Clone, projections: impl Iterator>, ) -> Result { - self.pretty_path_generic_args(print_prefix, params, substs, projections) + let args = args.filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => false, + _ => true, + } + }); + self.pretty_path_generic_args(print_prefix, args, projections) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c486628a4f546..94c954b01b154 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,7 +20,7 @@ use rustc::mir::interpret::GlobalId; use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc::ty::subst::{InternalSubsts, SubstsRef}; +use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; use rustc::ty::layout::VariantIdx; @@ -4304,8 +4304,7 @@ where F: Fn(DefId) -> Def { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _params: &[ty::GenericParamDef], - _substs: SubstsRef<'tcx>, + _args: impl Iterator> + Clone, _projections: impl Iterator>, ) -> Result { print_prefix(self) From c0c485c3ad7017c99137d8c9bc9afc729e7db534 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 24 Jan 2019 20:47:02 +0200 Subject: [PATCH 141/157] rustc: don't thread existential projections through path_generic_args. --- src/librustc/infer/error_reporting/mod.rs | 15 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/instance.rs | 2 +- src/librustc/ty/print/mod.rs | 46 ++-- src/librustc/ty/print/pretty.rs | 268 ++++++++++++--------- src/librustc/ty/structural_impls.rs | 5 +- src/librustc_codegen_utils/symbol_names.rs | 54 ++++- src/librustdoc/clean/mod.rs | 15 +- 8 files changed, 251 insertions(+), 156 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 06495510ede47..10c34aaf5b780 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::error::TypeError; use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable}; use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use std::{cmp, fmt, iter}; +use std::{cmp, fmt}; use syntax_pos::{Pos, Span}; mod note; @@ -458,6 +458,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Path = Vec; type Region = !; type Type = !; + type DynExistential = !; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -473,6 +474,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Err(NonTrivialPath) } + fn print_dyn_existential<'tcx>( + self: PrintCx<'_, '_, 'tcx, Self>, + _predicates: &'tcx ty::List>, + ) -> Result { + Err(NonTrivialPath) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -513,8 +521,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _args: impl Iterator> + Clone, - _projections: impl Iterator>, + _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } @@ -526,7 +533,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { PrintCx::new(self.tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, iter::empty()) + .print_def_path(def_id, None) }; // We compare strings because DefPath can be different diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5e2851e08ec4c..d1574bb322dd3 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2409,7 +2409,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { let f = &mut *fmt; PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.print_def_path(variant_def.did, Some(substs), iter::empty())?; + cx.print_def_path(variant_def.did, Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index b137d5f69c641..66c99a7c4fc09 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -178,7 +178,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with_tls_tcx(FmtPrinter::new(&mut *f, Namespace::ValueNS), |cx| { let substs = cx.tcx.lift(&self.substs).expect("could not lift for printing"); - cx.print_def_path(self.def_id(), Some(substs), iter::empty())?; + cx.print_def_path(self.def_id(), Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index d89bd84a34942..4e81533589e59 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -5,7 +5,6 @@ use crate::ty::subst::{Kind, Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; -use std::iter; use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. @@ -64,14 +63,14 @@ pub trait Printer: Sized { type Path; type Region; type Type; + type DynExistential; fn print_def_path( self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { - self.default_print_def_path(def_id, substs, projections) + self.default_print_def_path(def_id, substs) } fn print_impl_path( self: PrintCx<'_, '_, 'tcx, Self>, @@ -93,6 +92,11 @@ pub trait Printer: Sized { ty: Ty<'tcx>, ) -> Result; + fn print_dyn_existential( + self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result; + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -123,8 +127,7 @@ pub trait Printer: Sized { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result; } @@ -133,7 +136,6 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { self, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); let key = self.tcx.def_key(def_id); @@ -175,10 +177,10 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { let trait_ref = ty::TraitRef::new(parent_def_id, substs); cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) } else { - cx.print_def_path(parent_def_id, substs, iter::empty()) + cx.print_def_path(parent_def_id, substs) } } else { - cx.print_def_path(parent_def_id, None, iter::empty()) + cx.print_def_path(parent_def_id, None) } }; let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { @@ -197,7 +199,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { if let (Some(generics), Some(substs)) = (generics, substs) { let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(print_path, args, projections) + self.path_generic_args(print_path, args) } else { print_path(self) } @@ -209,13 +211,16 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { &self, generics: &'tcx ty::Generics, substs: SubstsRef<'tcx>, - ) -> impl Iterator> + Clone { + ) -> &'tcx [Kind<'tcx>] { + let mut own_params = generics.parent_count..generics.count(); + // Don't print args for `Self` parameters (of traits). - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; + if generics.has_self && own_params.start == 0 { + own_params.start = 1; + } // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = params.iter().rev().take_while(|param| { + own_params.end -= generics.params.iter().rev().take_while(|param| { match param.kind { ty::GenericParamDefKind::Lifetime => false, ty::GenericParamDefKind::Type { has_default, .. } => { @@ -226,9 +231,8 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) } }).count(); - params[..params.len() - num_supplied_defaults].iter().map(move |param| { - substs[param.index as usize] - }) + + &substs[own_params] } fn default_print_impl_path( @@ -261,7 +265,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { // trait-type, then fallback to a format that identifies // the module more clearly. self.path_append_impl( - |cx| cx.print_def_path(parent_def_id, None, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None), self_ty, impl_trait_ref, ) @@ -344,3 +348,11 @@ impl Print<'tcx, P> for Ty<'tcx> { cx.print_type(self) } } + +impl Print<'tcx, P> for &'tcx ty::List> { + type Output = P::DynExistential; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.print_dyn_existential(self) + } +} diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index a1e157685c9e2..d27e64b27a2e4 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -14,7 +14,6 @@ use syntax::symbol::InternedString; use std::cell::Cell; use std::fmt::{self, Write as _}; -use std::iter; use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. @@ -177,6 +176,7 @@ pub trait PrettyPrinter: Path = Self, Region = Self, Type = Self, + DynExistential = Self, > + fmt::Write { @@ -195,7 +195,7 @@ pub trait PrettyPrinter: def_id: DefId, substs: Option>, ) -> Result { - self.print_def_path(def_id, substs, iter::empty()) + self.print_def_path(def_id, substs) } fn in_binder( @@ -211,14 +211,13 @@ pub trait PrettyPrinter: fn comma_sep( mut self: PrintCx<'_, '_, 'tcx, Self>, mut elems: impl Iterator, - comma: &str, ) -> Result where T: Print<'tcx, Self, Output = Self, Error = Self::Error> { if let Some(first) = elems.next() { self = self.nest(|cx| first.print(cx))?; for elem in elems { - self.write_str(comma)?; + self.write_str(", ")?; self = self.nest(|cx| elem.print(cx))?; } } @@ -272,7 +271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); let _ = PrintCx::new(self, FmtPrinter::new(&mut s, ns)) - .print_def_path(def_id, None, iter::empty()); + .print_def_path(def_id, None); s } } @@ -317,7 +316,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok((if !span.is_dummy() { - self.print_def_path(def_id, None, iter::empty())? + self.print_def_path(def_id, None)? } else { self.path_crate(cnum)? }, true)); @@ -485,33 +484,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { cx.ok() }) } - - pub fn pretty_path_generic_args( - mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, - mut args: impl Iterator>, - mut projections: impl Iterator>, - ) -> Result { - self = self.nest(print_prefix)?; - - let arg0 = args.next(); - let projection0 = projections.next(); - if arg0.is_none() && projection0.is_none() { - return self.ok(); - } - let args = arg0.into_iter().chain(args); - let projections = projection0.into_iter().chain(projections); - - self.generic_delimiters(|mut cx| { - cx = cx.nest(|cx| cx.comma_sep(args, ", "))?; - if arg0.is_some() && projection0.is_some() { - write!(cx, ", ")?; - } - cx.comma_sep(projections, ", ") - }) - } } // HACK(eddyb) boxed to avoid moving around a large struct by-value. @@ -570,12 +542,12 @@ impl Printer for FmtPrinter { type Path = Self; type Region = Self; type Type = Self; + type DynExistential = Self; fn print_def_path( mut self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. @@ -590,7 +562,7 @@ impl Printer for FmtPrinter { if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(|cx| cx.ok(), args, projections) + self.path_generic_args(|cx| cx.ok(), args) } else { self.ok() }; @@ -615,13 +587,13 @@ impl Printer for FmtPrinter { let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; let span = self.tcx.def_span(def_id); return self.path_append( - |cx| cx.print_def_path(parent_def_id, None, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None), &format!("", span), ); } } - self.default_print_def_path(def_id, substs, projections) + self.default_print_def_path(def_id, substs) } fn print_region( @@ -638,6 +610,13 @@ impl Printer for FmtPrinter { self.pretty_print_type(ty) } + fn print_dyn_existential( + self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result { + self.pretty_print_dyn_existential(predicates) + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -703,27 +682,33 @@ impl Printer for FmtPrinter { Ok(path) } fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result { + self = self.nest(print_prefix)?; + // Don't print `'_` if there's no unerased regions. - let print_regions = args.clone().any(|arg| { + let print_regions = args.iter().any(|arg| { match arg.unpack() { UnpackedKind::Lifetime(r) => *r != ty::ReErased, _ => false, } }); - let args = args.filter(|arg| { + let args = args.iter().cloned().filter(|arg| { match arg.unpack() { UnpackedKind::Lifetime(_) => print_regions, _ => true, } }); - self.pretty_path_generic_args(print_prefix, args, projections) + + if args.clone().next().is_some() { + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + self.ok() + } } } @@ -745,7 +730,7 @@ impl PrettyPrinter for FmtPrinter { substs: Option>, ) -> Result { let was_in_value = std::mem::replace(&mut self.in_value, true); - let mut path = self.print_def_path(def_id, substs, iter::empty())?; + let mut path = self.print_def_path(def_id, substs)?; path.in_value = was_in_value; Ok(path) @@ -995,7 +980,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Adt(def, substs) => { - nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); + nest!(|cx| cx.print_def_path(def.did, Some(substs))); } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -1008,7 +993,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); + nest!(|cx| cx.print_def_path(def_id, None)); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -1184,6 +1169,105 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self.ok() } + fn pretty_print_dyn_existential( + mut self, + predicates: &'tcx ty::List>, + ) -> Result { + define_scoped_cx!(self); + + // Generate the main trait ref, including associated types. + let mut first = true; + + if let Some(principal) = predicates.principal() { + nest!(|cx| cx.print_def_path(principal.def_id, None)); + + let mut resugared = false; + + // Special-case `Fn(...) -> ...` and resugar it. + let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(principal.def_id); + if !self.tcx.sess.verbose() && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { + let mut projections = predicates.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); + resugared = true; + } + } + } + + // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`, + // in order to place the projections inside the `<...>`. + if !resugared { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = self.tcx.mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(self.tcx, dummy_self); + + let args = self.generic_args_to_print( + self.tcx.generics_of(principal.def_id), + principal.substs, + ); + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let mut args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + let mut projections = predicates.projection_bounds(); + + let arg0 = args.next(); + let projection0 = projections.next(); + if arg0.is_some() || projection0.is_some() { + let args = arg0.into_iter().chain(args); + let projections = projection0.into_iter().chain(projections); + + nest!(|cx| cx.generic_delimiters(|mut cx| { + cx = cx.nest(|cx| cx.comma_sep(args))?; + if arg0.is_some() && projection0.is_some() { + write!(cx, ", ")?; + } + cx.comma_sep(projections) + })); + } + } + first = false; + } + + // Builtin bounds. + // FIXME(eddyb) avoid printing twice (needed to ensure + // that the auto traits are sorted *and* printed via cx). + let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { + (self.tcx.def_path_str(did), did) + }).collect(); + + // The auto traits come ordered by `DefPathHash`. While + // `DefPathHash` is *stable* in the sense that it depends on + // neither the host nor the phase of the moon, it depends + // "pseudorandomly" on the compiler version and the target. + // + // To avoid that causing instabilities in compiletest + // output, sort the auto-traits alphabetically. + auto_traits.sort(); + + for (_, def_id) in auto_traits { + if !first { + p!(write(" + ")); + } + first = false; + + nest!(|cx| cx.print_def_path(def_id, None)); + } + + self.ok() + } + pub fn pretty_fn_sig( mut self, inputs: &[Ty<'tcx>], @@ -1399,6 +1483,7 @@ macro_rules! define_print_and_forward_display { forward_display_to_print!(ty::RegionKind); forward_display_to_print!(Ty<'tcx>); +forward_display_to_print!(&'tcx ty::List>); forward_display_to_print!( ty::Binder); define_print_and_forward_display! { @@ -1412,70 +1497,6 @@ define_print_and_forward_display! { define_print_and_forward_display! { (self, cx): - &'tcx ty::List> { - // Generate the main trait ref, including associated types. - let mut first = true; - - if let Some(principal) = self.principal() { - let mut resugared_principal = false; - - // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); - if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() { - if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { - let mut projections = self.projection_bounds(); - if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); - nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); - resugared_principal = true; - } - } - } - - if !resugared_principal { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let principal = principal.with_self_ty(cx.tcx, dummy_self); - nest!(|cx| cx.print_def_path( - principal.def_id, - Some(principal.substs), - self.projection_bounds(), - )); - } - first = false; - } - - // Builtin bounds. - // FIXME(eddyb) avoid printing twice (needed to ensure - // that the auto traits are sorted *and* printed via cx). - let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - (cx.tcx.def_path_str(did), did) - }).collect(); - - // The auto traits come ordered by `DefPathHash`. While - // `DefPathHash` is *stable* in the sense that it depends on - // neither the host nor the phase of the moon, it depends - // "pseudorandomly" on the compiler version and the target. - // - // To avoid that causing instabilities in compiletest - // output, sort the auto-traits alphabetically. - auto_traits.sort(); - - for (_, def_id) in auto_traits { - if !first { - p!(write(" + ")); - } - first = false; - - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); - } - } - - ty::ExistentialProjection<'tcx> { - let name = cx.tcx.associated_item(self.item_def_id).ident; - p!(write("{}=", name), print(self.ty)) - } - &'tcx ty::List> { p!(write("{{")); let mut tys = self.iter(); @@ -1494,14 +1515,27 @@ define_print_and_forward_display! { } ty::ExistentialTraitRef<'tcx> { + // Use a type that can't appear in defaults of type parameters. let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - - let trait_ref = *ty::Binder::bind(*self) - .with_self_ty(cx.tcx, dummy_self) - .skip_binder(); + let trait_ref = self.with_self_ty(cx.tcx, dummy_self); p!(print(trait_ref)) } + ty::ExistentialProjection<'tcx> { + let name = cx.tcx.associated_item(self.item_def_id).ident; + p!(write("{}=", name), print(self.ty)) + } + + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + nest!(|cx| cx.print_def_path(def_id, None)) + } + } + } + ty::FnSig<'tcx> { if self.unsafety == hir::Unsafety::Unsafe { p!(write("unsafe ")); @@ -1531,7 +1565,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); + nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs))); } ConstValue<'tcx> { @@ -1575,7 +1609,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); + nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs))); } ty::ClosureKind { @@ -1596,7 +1630,7 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty())); + nest!(|cx| cx.print_def_path(trait_def_id, None)); p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index dfb7e64d98bcb..32a39c2eb883d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -14,7 +14,6 @@ use smallvec::SmallVec; use crate::mir::interpret; use std::fmt; -use std::iter; use std::marker::PhantomData; use std::rc::Rc; @@ -36,7 +35,7 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.def_id, None, iter::empty())?; + cx.print_def_path(self.def_id, None)?; Ok(()) }) } @@ -45,7 +44,7 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.did, None, iter::empty())?; + cx.print_def_path(self.did, None)?; Ok(()) }) } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 93e7e495d4ede..9620c3efda07f 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -92,7 +92,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::print::{PrettyPrinter, PrintCx, Printer}; +use rustc::ty::print::{PrettyPrinter, PrintCx, Printer, Print}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -106,7 +106,6 @@ use syntax_pos::symbol::Symbol; use log::debug; use std::fmt::{self, Write}; -use std::iter; use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { @@ -225,7 +224,7 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { PrintCx::new(tcx, SymbolPath::new(tcx)) - .print_def_path(def_id, None, iter::empty()) + .print_def_path(def_id, None) .unwrap() .into_interned() } @@ -409,6 +408,7 @@ impl Printer for SymbolPath { type Path = Self; type Region = Self; type Type = Self; + type DynExistential = Self; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -429,12 +429,27 @@ impl Printer for SymbolPath { ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | ty::Closure(def_id, ty::ClosureSubsts { substs }) | ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { - self.print_def_path(def_id, Some(substs), iter::empty()) + self.print_def_path(def_id, Some(substs)) } _ => self.pretty_print_type(ty), } } + fn print_dyn_existential( + mut self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result { + let mut first = false; + for p in predicates { + if !first { + write!(self, "+")?; + } + first = false; + self = self.nest(|cx| p.print(cx))?; + } + self.ok() + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -499,20 +514,26 @@ impl Printer for SymbolPath { Ok(path) } fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result { - let args = args.filter(|arg| { + self = self.nest(print_prefix)?; + + let args = args.iter().cloned().filter(|arg| { match arg.unpack() { UnpackedKind::Lifetime(_) => false, _ => true, } }); - self.pretty_path_generic_args(print_prefix, args, projections) + + if args.clone().next().is_some() { + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + self.ok() + } } } @@ -523,6 +544,21 @@ impl PrettyPrinter for SymbolPath { ) -> bool { false } + fn comma_sep( + mut self: PrintCx<'_, '_, 'tcx, Self>, + mut elems: impl Iterator, + ) -> Result + where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + { + if let Some(first) = elems.next() { + self = self.nest(|cx| first.print(cx))?; + for elem in elems { + self.write_str(",")?; + self = self.nest(|cx| elem.print(cx))?; + } + } + self.ok() + } fn generic_delimiters<'gcx, 'tcx>( mut self: PrintCx<'_, 'gcx, 'tcx, Self>, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 94c954b01b154..6822de2bcebae 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,7 +39,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::default::Default; use std::{mem, slice, vec}; -use std::iter::{self, FromIterator, once}; +use std::iter::{FromIterator, once}; use std::rc::Rc; use std::str::FromStr; use std::cell::RefCell; @@ -4235,6 +4235,7 @@ where F: Fn(DefId) -> Def { type Path = Vec; type Region = (); type Type = (); + type DynExistential = (); fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -4250,6 +4251,13 @@ where F: Fn(DefId) -> Def { Ok(()) } + fn print_dyn_existential<'tcx>( + self: PrintCx<'_, '_, 'tcx, Self>, + _predicates: &'tcx ty::List>, + ) -> Result { + Ok(()) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -4304,15 +4312,14 @@ where F: Fn(DefId) -> Def { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _args: impl Iterator> + Clone, - _projections: impl Iterator>, + _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } } let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, iter::empty()) + .print_def_path(def_id, None) .unwrap(); hir::Path { From 2a656828acc6fa619e2e83f928ca21f2281c911b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 25 Jan 2019 02:34:19 +0200 Subject: [PATCH 142/157] rustc: remove the ability for pretty-printers to override nesting. --- src/librustc/ty/print/pretty.rs | 121 ++++++++++----------- src/librustc_codegen_utils/symbol_names.rs | 8 +- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index d27e64b27a2e4..da01fd11a3f88 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -20,8 +20,8 @@ use std::ops::{Deref, DerefMut}; use super::*; macro_rules! nest { - ($closure:expr) => { - scoped_cx!() = scoped_cx!().nest($closure)? + ($e:expr) => { + scoped_cx!() = PrintCx::new(scoped_cx!().tcx, $e?) } } macro_rules! print_inner { @@ -29,7 +29,7 @@ macro_rules! print_inner { write!(scoped_cx!(), $($data),+)? }; ($kind:ident ($data:expr)) => { - nest!(|cx| $data.$kind(cx)) + nest!($data.$kind(scoped_cx!())) }; } macro_rules! p { @@ -180,15 +180,6 @@ pub trait PrettyPrinter: > + fmt::Write { - /// Enter a nested print context, for pretty-printing - /// nested components in some larger context. - fn nest<'a, 'gcx, 'tcx, E>( - self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result, E> { - Ok(PrintCx::new(self.tcx, f(self)?)) - } - /// Like `print_def_path` but for value paths. fn print_value_path( self: PrintCx<'_, '_, 'tcx, Self>, @@ -214,11 +205,13 @@ pub trait PrettyPrinter: ) -> Result where T: Print<'tcx, Self, Output = Self, Error = Self::Error> { + define_scoped_cx!(self); + if let Some(first) = elems.next() { - self = self.nest(|cx| first.print(cx))?; + nest!(first.print(self)); for elem in elems { self.write_str(", ")?; - self = self.nest(|cx| elem.print(cx))?; + nest!(elem.print(self)); } } self.ok() @@ -355,9 +348,9 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // the entire path will succeed or not. To support printers that do not // implement `PrettyPrinter`, a `Vec` or linked list on the stack would // need to be built, before starting to print anything. - let mut prefix_success = false; - nest!(|cx| { - let (path, success) = cx.try_print_visible_def_path(visible_parent)?; + let prefix_success; + nest!({ + let (path, success) = self.try_print_visible_def_path(visible_parent)?; prefix_success = success; Ok(path) }); @@ -470,7 +463,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self = self.nest(print_prefix)?; + self = PrintCx::new(self.tcx, print_prefix(self)?); self.generic_delimiters(|mut cx| { define_scoped_cx!(cx); @@ -492,7 +485,7 @@ pub struct FmtPrinter(Box>); pub struct FmtPrinterData { fmt: F, - empty: bool, + empty_path: bool, in_value: bool, used_region_names: FxHashSet, @@ -519,7 +512,7 @@ impl FmtPrinter { pub fn new(fmt: F, ns: Namespace) -> Self { FmtPrinter(Box::new(FmtPrinterData { fmt, - empty: true, + empty_path: false, in_value: ns == Namespace::ValueNS, used_region_names: Default::default(), region_index: 0, @@ -531,7 +524,6 @@ impl FmtPrinter { impl fmt::Write for FmtPrinter { fn write_str(&mut self, s: &str) -> fmt::Result { - self.empty &= s.is_empty(); self.fmt.write_str(s) } } @@ -549,16 +541,18 @@ impl Printer for FmtPrinter { def_id: DefId, substs: Option>, ) -> Result { + define_scoped_cx!(self); + // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. let generics = substs.map(|_| self.tcx.generics_of(def_id)); if generics.as_ref().and_then(|g| g.parent).is_none() { - let mut visible_path_success = false; - self = self.nest(|cx| { - let (path, success) = cx.try_print_visible_def_path(def_id)?; + let visible_path_success; + nest!({ + let (path, success) = self.try_print_visible_def_path(def_id)?; visible_path_success = success; Ok(path) - })?; + }); if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { let args = self.generic_args_to_print(generics, substs); @@ -621,15 +615,18 @@ impl Printer for FmtPrinter { mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, ) -> Result { + self.empty_path = true; if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { write!(self, "{}", keywords::Crate.name())?; + self.empty_path = false; } } } else { write!(self, "{}", self.tcx.crate_name(cnum))?; + self.empty_path = false; } self.ok() } @@ -638,7 +635,9 @@ impl Printer for FmtPrinter { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self.pretty_path_qualified(self_ty, trait_ref) + let mut path = self.pretty_path_qualified(self_ty, trait_ref)?; + path.empty_path = false; + Ok(path) } fn path_append_impl<'gcx, 'tcx>( @@ -649,17 +648,16 @@ impl Printer for FmtPrinter { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self.pretty_path_append_impl(|cx| { + let mut path = self.pretty_path_append_impl(|cx| { let mut path = print_prefix(cx)?; - - // HACK(eddyb) this accounts for `generic_delimiters` - // printing `::<` instead of `<` if `in_value` is set. - if !path.empty && !path.in_value { + if !path.empty_path { write!(path, "::")?; } Ok(path) - }, self_ty, trait_ref) + }, self_ty, trait_ref)?; + path.empty_path = false; + Ok(path) } fn path_append<'gcx, 'tcx>( self: PrintCx<'_, 'gcx, 'tcx, Self>, @@ -673,10 +671,11 @@ impl Printer for FmtPrinter { // FIXME(eddyb) `text` should never be empty, but it // currently is for `extern { ... }` "foreign modules". if !text.is_empty() { - if !path.empty { + if !path.empty_path { write!(path, "::")?; } write!(path, "{}", text)?; + path.empty_path = false; } Ok(path) @@ -688,7 +687,9 @@ impl Printer for FmtPrinter { ) -> Result, args: &[Kind<'tcx>], ) -> Result { - self = self.nest(print_prefix)?; + define_scoped_cx!(self); + + nest!(print_prefix(self)); // Don't print `'_` if there's no unerased regions. let print_regions = args.iter().any(|arg| { @@ -705,6 +706,9 @@ impl Printer for FmtPrinter { }); if args.clone().next().is_some() { + if self.in_value { + write!(self, "::")?; + } self.generic_delimiters(|cx| cx.comma_sep(args)) } else { self.ok() @@ -713,17 +717,6 @@ impl Printer for FmtPrinter { } impl PrettyPrinter for FmtPrinter { - fn nest<'a, 'gcx, 'tcx, E>( - mut self: PrintCx<'a, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result, E> { - let tcx = self.tcx; - let was_empty = std::mem::replace(&mut self.empty, true); - let mut inner = f(self)?; - inner.empty &= was_empty; - Ok(PrintCx::new(tcx, inner)) - } - fn print_value_path( mut self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, @@ -749,11 +742,7 @@ impl PrettyPrinter for FmtPrinter { mut self: PrintCx<'_, 'gcx, 'tcx, Self>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, ) -> Result { - if !self.empty && self.in_value { - write!(self, "::<")?; - } else { - write!(self, "<")?; - } + write!(self, "<")?; let was_in_value = std::mem::replace(&mut self.in_value, false); let mut inner = f(self)?; @@ -957,7 +946,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ty::FnDef(def_id, substs) => { let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); p!(print(sig), write(" {{")); - nest!(|cx| cx.print_value_path(def_id, Some(substs))); + nest!(self.print_value_path(def_id, Some(substs))); p!(write("}}")) } ty::FnPtr(ref bare_fn) => { @@ -980,7 +969,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Adt(def, substs) => { - nest!(|cx| cx.print_def_path(def.did, Some(substs))); + nest!(self.print_def_path(def.did, Some(substs))); } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -993,7 +982,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(|cx| cx.print_def_path(def_id, None)); + nest!(self.print_def_path(def_id, None)); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -1094,7 +1083,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" "), print(witness), write("]")) }, ty::GeneratorWitness(types) => { - nest!(|cx| cx.in_binder(&types)) + nest!(self.in_binder(&types)) } ty::Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, self.tcx); @@ -1179,7 +1168,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let mut first = true; if let Some(principal) = predicates.principal() { - nest!(|cx| cx.print_def_path(principal.def_id, None)); + nest!(self.print_def_path(principal.def_id, None)); let mut resugared = false; @@ -1189,7 +1178,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = predicates.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); + nest!(self.pretty_fn_sig(args, false, proj.ty)); resugared = true; } } @@ -1228,8 +1217,8 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let args = arg0.into_iter().chain(args); let projections = projection0.into_iter().chain(projections); - nest!(|cx| cx.generic_delimiters(|mut cx| { - cx = cx.nest(|cx| cx.comma_sep(args))?; + nest!(self.generic_delimiters(|mut cx| { + cx = PrintCx::new(cx.tcx, cx.comma_sep(args)?); if arg0.is_some() && projection0.is_some() { write!(cx, ", ")?; } @@ -1262,7 +1251,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } first = false; - nest!(|cx| cx.print_def_path(def_id, None)); + nest!(self.print_def_path(def_id, None)); } self.ok() @@ -1531,7 +1520,7 @@ define_print_and_forward_display! { ty::ExistentialPredicate::Trait(x) => p!(print(x)), ty::ExistentialPredicate::Projection(x) => p!(print(x)), ty::ExistentialPredicate::AutoTrait(def_id) => { - nest!(|cx| cx.print_def_path(def_id, None)) + nest!(cx.print_def_path(def_id, None)) } } } @@ -1546,7 +1535,7 @@ define_print_and_forward_display! { } p!(write("fn")); - nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + nest!(cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } ty::InferTy { @@ -1565,7 +1554,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs))); + nest!(cx.print_def_path(self.def_id, Some(self.substs))); } ConstValue<'tcx> { @@ -1609,7 +1598,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs))); + nest!(cx.print_def_path(self.item_def_id, Some(self.substs))); } ty::ClosureKind { @@ -1630,17 +1619,17 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(|cx| cx.print_def_path(trait_def_id, None)); + nest!(cx.print_def_path(trait_def_id, None)); p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `")); - nest!(|cx| cx.print_value_path(closure_def_id, None)); + nest!(cx.print_value_path(closure_def_id, None)); p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `")); - nest!(|cx| cx.print_value_path(def_id, Some(substs))); + nest!(cx.print_value_path(def_id, Some(substs))); p!(write("` can be evaluated")) } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 9620c3efda07f..084b86b1eb424 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -445,7 +445,7 @@ impl Printer for SymbolPath { write!(self, "+")?; } first = false; - self = self.nest(|cx| p.print(cx))?; + self = PrintCx::new(self.tcx, p.print(self)?); } self.ok() } @@ -520,7 +520,7 @@ impl Printer for SymbolPath { ) -> Result, args: &[Kind<'tcx>], ) -> Result { - self = self.nest(print_prefix)?; + self = PrintCx::new(self.tcx, print_prefix(self)?); let args = args.iter().cloned().filter(|arg| { match arg.unpack() { @@ -551,10 +551,10 @@ impl PrettyPrinter for SymbolPath { where T: Print<'tcx, Self, Output = Self, Error = Self::Error> { if let Some(first) = elems.next() { - self = self.nest(|cx| first.print(cx))?; + self = PrintCx::new(self.tcx, first.print(self)?); for elem in elems { self.write_str(",")?; - self = self.nest(|cx| elem.print(cx))?; + self = PrintCx::new(self.tcx, elem.print(self)?); } } self.ok() From 52b4f2daa0e1a9c4aea4b729c0bcd46b5991f8a3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 25 Jan 2019 12:11:50 +0200 Subject: [PATCH 143/157] rustc: remove PrintCx from ty::Print and rely on printers carrying TyCtxt. --- src/librustc/infer/error_reporting/mod.rs | 54 +- .../infer/error_reporting/need_type_info.rs | 4 +- .../nice_region_error/placeholder_error.rs | 10 +- src/librustc/mir/mod.rs | 9 +- src/librustc/ty/instance.rs | 9 +- src/librustc/ty/print/mod.rs | 143 +- src/librustc/ty/print/pretty.rs | 1394 ++++++++--------- src/librustc/ty/structural_impls.rs | 30 +- src/librustc_codegen_utils/symbol_names.rs | 177 ++- .../borrow_check/error_reporting.rs | 8 +- src/librustdoc/clean/mod.rs | 57 +- 11 files changed, 919 insertions(+), 976 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 10c34aaf5b780..52b4288103813 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -445,14 +445,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sp: Span, ) { use hir::def_id::CrateNum; - use ty::print::{PrintCx, Printer}; + use ty::print::Printer; use ty::subst::Kind; - struct AbsolutePathPrinter; + struct AbsolutePathPrinter<'a, 'gcx, 'tcx> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + } struct NonTrivialPath; - impl Printer for AbsolutePathPrinter { + impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> { type Error = NonTrivialPath; type Path = Vec; @@ -460,67 +462,65 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Type = !; type DynExistential = !; + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { Err(NonTrivialPath) } - fn print_type<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_type( + self, _ty: Ty<'tcx>, ) -> Result { Err(NonTrivialPath) } - fn print_dyn_existential<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_dyn_existential( + self, _predicates: &'tcx ty::List>, ) -> Result { Err(NonTrivialPath) } fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } - fn path_qualified<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn path_qualified( + self, _self_ty: Ty<'tcx>, _trait_ref: Option>, ) -> Result { Err(NonTrivialPath) } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - _print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + _print_prefix: impl FnOnce(Self) -> Result, _self_ty: Ty<'tcx>, _trait_ref: Option>, ) -> Result { Err(NonTrivialPath) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) @@ -532,7 +532,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { - PrintCx::new(self.tcx, AbsolutePathPrinter) + AbsolutePathPrinter { tcx: self.tcx } .print_def_path(def_id, None) }; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index f649309004bfc..0a83b839201ed 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -80,11 +80,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); if let Some(highlight) = highlight { printer.region_highlight_mode = highlight; } - let _ = ty.print(ty::print::PrintCx::new(self.tcx, printer)); + let _ = ty.print(printer); s } diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index fd01ed85ef721..e708454b5b672 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -337,17 +337,17 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } } - impl<'tcx, T> fmt::Display for Highlighted<'_, '_, 'tcx, T> - where T: for<'a, 'b> Print<'tcx, - FmtPrinter<&'a mut fmt::Formatter<'b>>, + impl<'a, 'gcx, 'tcx, T> fmt::Display for Highlighted<'a, 'gcx, 'tcx, T> + where T: for<'b, 'c> Print<'gcx, 'tcx, + FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>, Error = fmt::Error, >, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut printer = ty::print::FmtPrinter::new(f, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.tcx, f, Namespace::TypeNS); printer.region_highlight_mode = self.highlight; - self.value.print(ty::print::PrintCx::new(self.tcx, printer))?; + self.value.print(printer)?; Ok(()) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d1574bb322dd3..3218f8ea5de48 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -34,7 +34,7 @@ use crate::ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; -use crate::ty::print::{FmtPrinter, Printer, PrintCx}; +use crate::ty::print::{FmtPrinter, Printer}; pub use crate::mir::interpret::AssertMessage; @@ -2407,9 +2407,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { let variant_def = &adt_def.variants[variant]; let f = &mut *fmt; - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |cx| { - let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.print_def_path(variant_def.did, Some(substs))?; + ty::tls::with(|tcx| { + let substs = tcx.lift(&substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, f, Namespace::ValueNS) + .print_def_path(variant_def.did, Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 66c99a7c4fc09..89d956c8bfae3 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -2,7 +2,7 @@ use crate::hir::Unsafety; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; -use crate::ty::print::{FmtPrinter, Printer, PrintCx}; +use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; @@ -176,9 +176,10 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(&mut *f, Namespace::ValueNS), |cx| { - let substs = cx.tcx.lift(&self.substs).expect("could not lift for printing"); - cx.print_def_path(self.def_id(), Some(substs))?; + ty::tls::with(|tcx| { + let substs = tcx.lift(&self.substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS) + .print_def_path(self.def_id(), Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 4e81533589e59..ad17a8114cabf 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -5,59 +5,18 @@ use crate::ty::subst::{Kind, Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; -use std::ops::{Deref, DerefMut}; - // `pretty` is a separate module only for organization. mod pretty; pub use self::pretty::*; -pub struct PrintCx<'a, 'gcx, 'tcx, P> { - pub tcx: TyCtxt<'a, 'gcx, 'tcx>, - inner: P, -} - -impl

Deref for PrintCx<'_, '_, '_, P> { - type Target = P; - fn deref(&self) -> &P { - &self.inner - } -} - -impl

DerefMut for PrintCx<'_, '_, '_, P> { - fn deref_mut(&mut self) -> &mut P { - &mut self.inner - } -} - -impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, inner: P) -> Self { - PrintCx { - tcx, - inner, - } - } - - pub fn with_tls_tcx(inner: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { - ty::tls::with(|tcx| f(PrintCx::new(tcx, inner))) - } - - pub fn into_inner(self) -> P { - self.inner - } - - pub fn ok(self) -> Result { - Ok(self.into_inner()) - } -} - -pub trait Print<'tcx, P> { +pub trait Print<'gcx, 'tcx, P> { type Output; type Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result; + fn print(&self, cx: P) -> Result; } -pub trait Printer: Sized { +pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { type Error; type Path; @@ -65,15 +24,17 @@ pub trait Printer: Sized { type Type; type DynExistential; + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; + fn print_def_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, def_id: DefId, substs: Option>, ) -> Result { self.default_print_def_path(def_id, substs) } fn print_impl_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, impl_def_id: DefId, substs: Option>, self_ty: Ty<'tcx>, @@ -83,62 +44,56 @@ pub trait Printer: Sized { } fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, region: ty::Region<'_>, ) -> Result; fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, ty: Ty<'tcx>, ) -> Result; fn print_dyn_existential( - self: PrintCx<'_, '_, 'tcx, Self>, + self, predicates: &'tcx ty::List>, ) -> Result; fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result; fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result; - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result; - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result; - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, args: &[Kind<'tcx>], ) -> Result; -} -impl PrintCx<'_, 'gcx, 'tcx, P> { - pub fn default_print_def_path( + // Defaults (should not be overriden): + + fn default_print_def_path( self, def_id: DefId, substs: Option>, - ) -> Result { + ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); - let key = self.tcx.def_key(def_id); + let key = self.tcx().def_key(def_id); debug!("default_print_def_path: key={:?}", key); match key.disambiguated_data.data { @@ -148,29 +103,29 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { } DefPathData::Impl => { - let mut self_ty = self.tcx.type_of(def_id); + let mut self_ty = self.tcx().type_of(def_id); if let Some(substs) = substs { - self_ty = self_ty.subst(self.tcx, substs); + self_ty = self_ty.subst(self.tcx(), substs); } - let mut impl_trait_ref = self.tcx.impl_trait_ref(def_id); + let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); if let Some(substs) = substs { - impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); + impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs); } self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } _ => { - let generics = substs.map(|_| self.tcx.generics_of(def_id)); + let generics = substs.map(|_| self.tcx().generics_of(def_id)); let generics_parent = generics.as_ref().and_then(|g| g.parent); let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let print_parent_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + let print_parent_path = |cx: Self| { if let Some(generics_parent_def_id) = generics_parent { assert_eq!(parent_def_id, generics_parent_def_id); // FIXME(eddyb) try to move this into the parent's printing // logic, instead of doing it when printing the child. - let parent_generics = cx.tcx.generics_of(parent_def_id); + let parent_generics = cx.tcx().generics_of(parent_def_id); let parent_has_own_self = parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { @@ -183,7 +138,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { cx.print_def_path(parent_def_id, None) } }; - let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + let print_path = |cx: Self| { match key.disambiguated_data.data { // Skip `::{{constructor}}` on tuple/unit structs. DefPathData::StructCtor => print_parent_path(cx), @@ -207,7 +162,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { } } - pub fn generic_args_to_print( + fn generic_args_to_print( &self, generics: &'tcx ty::Generics, substs: SubstsRef<'tcx>, @@ -225,7 +180,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { ty::GenericParamDefKind::Lifetime => false, ty::GenericParamDefKind::Type { has_default, .. } => { has_default && substs[param.index as usize] == Kind::from( - self.tcx.type_of(param.def_id).subst(self.tcx, substs) + self.tcx().type_of(param.def_id).subst(self.tcx(), substs) ) } ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) @@ -241,7 +196,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { _substs: Option>, self_ty: Ty<'tcx>, impl_trait_ref: Option>, - ) -> Result { + ) -> Result { debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", impl_def_id, self_ty, impl_trait_ref); @@ -250,14 +205,14 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); + let parent_def_id = self.tcx().parent(impl_def_id).unwrap(); let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, - Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), + Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id), }; let in_trait_mod = match impl_trait_ref { None => false, - Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), + Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id), }; if !in_self_mod && !in_trait_mod { @@ -325,34 +280,36 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { } } -impl Print<'tcx, P> for ty::RegionKind { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind { type Output = P::Region; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_region(self) } } -impl Print<'tcx, P> for ty::Region<'_> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> { type Output = P::Region; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_region(self) } } -impl Print<'tcx, P> for Ty<'tcx> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> { type Output = P::Type; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_type(self) } } -impl Print<'tcx, P> for &'tcx ty::List> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for &'tcx ty::List> +{ type Output = P::DynExistential; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_dyn_existential(self) } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index da01fd11a3f88..fff4ca822d20e 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -19,17 +19,12 @@ use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. use super::*; -macro_rules! nest { - ($e:expr) => { - scoped_cx!() = PrintCx::new(scoped_cx!().tcx, $e?) - } -} macro_rules! print_inner { (write ($($data:expr),+)) => { write!(scoped_cx!(), $($data),+)? }; ($kind:ident ($data:expr)) => { - nest!($data.$kind(scoped_cx!())) + scoped_cx!() = $data.$kind(scoped_cx!())? }; } macro_rules! p { @@ -170,8 +165,8 @@ impl RegionHighlightMode { } /// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: - Printer< +pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: + Printer<'gcx, 'tcx, Error = fmt::Error, Path = Self, Region = Self, @@ -182,7 +177,7 @@ pub trait PrettyPrinter: { /// Like `print_def_path` but for value paths. fn print_value_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, def_id: DefId, substs: Option>, ) -> Result { @@ -190,93 +185,54 @@ pub trait PrettyPrinter: } fn in_binder( - self: PrintCx<'_, '_, 'tcx, Self>, + self, value: &ty::Binder, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> { value.skip_binder().print(self) } /// Print comma-separated elements. fn comma_sep( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, mut elems: impl Iterator, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> { - define_scoped_cx!(self); - if let Some(first) = elems.next() { - nest!(first.print(self)); + self = first.print(self)?; for elem in elems { self.write_str(", ")?; - nest!(elem.print(self)); + self = elem.print(self)?; } } - self.ok() + Ok(self) } /// Print `<...>` around what `f` prints. - fn generic_delimiters<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + fn generic_delimiters( + self, + f: impl FnOnce(Self) -> Result, ) -> Result; /// Return `true` if the region should be printed in /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. /// This is typically the case for all non-`'_` regions. fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, + &self, region: ty::Region<'_>, ) -> bool; -} - -impl fmt::Write for PrintCx<'_, '_, '_, P> { - fn write_str(&mut self, s: &str) -> fmt::Result { - (**self).write_str(s) - } -} - -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always - // (but also some things just print a `DefId` generally so maybe we need this?) - fn guess_def_namespace(self, def_id: DefId) -> Namespace { - match self.def_key(def_id).disambiguated_data.data { - DefPathData::ValueNs(..) | - DefPathData::EnumVariant(..) | - DefPathData::Field(..) | - DefPathData::AnonConst | - DefPathData::ConstParam(..) | - DefPathData::ClosureExpr | - DefPathData::StructCtor => Namespace::ValueNS, - - DefPathData::MacroDef(..) => Namespace::MacroNS, - - _ => Namespace::TypeNS, - } - } - /// Returns a string identifying this `DefId. This string is - /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { - let ns = self.guess_def_namespace(def_id); - debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); - let mut s = String::new(); - let _ = PrintCx::new(self, FmtPrinter::new(&mut s, ns)) - .print_def_path(def_id, None); - s - } -} + // Defaults (should not be overriden): -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. fn try_print_visible_def_path( mut self, def_id: DefId, - ) -> Result<(P, bool), P::Error> { + ) -> Result<(Self, bool), Self::Error> { define_scoped_cx!(self); debug!("try_print_visible_def_path: def_id={:?}", def_id); @@ -300,7 +256,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // 2. for an extern inferred from a path or an indirect crate, // where there is no explicit `extern crate`, we just prepend // the crate name. - match *self.tcx.extern_crate(def_id) { + match *self.tcx().extern_crate(def_id) { Some(ExternCrate { src: ExternCrateSource::Extern(def_id), direct: true, @@ -322,12 +278,12 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } if def_id.is_local() { - return self.ok().map(|path| (path, false)); + return Ok((self, false)); } - let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); + let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE); - let mut cur_def_key = self.tcx.def_key(def_id); + let mut cur_def_key = self.tcx().def_key(def_id); debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); // For a UnitStruct or TupleStruct we want the name of its parent rather than . @@ -337,27 +293,22 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), }; - cur_def_key = self.tcx.def_key(parent); + cur_def_key = self.tcx().def_key(parent); } let visible_parent = match visible_parent_map.get(&def_id).cloned() { Some(parent) => parent, - None => return self.ok().map(|path| (path, false)), - }; - // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether - // the entire path will succeed or not. To support printers that do not - // implement `PrettyPrinter`, a `Vec` or linked list on the stack would - // need to be built, before starting to print anything. - let prefix_success; - nest!({ - let (path, success) = self.try_print_visible_def_path(visible_parent)?; - prefix_success = success; - Ok(path) - }); - if !prefix_success { - return self.ok().map(|path| (path, false)); + None => return Ok((self, false)), }; - let actual_parent = self.tcx.parent(def_id); + // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid + // knowing ahead of time whether the entire path will succeed or not. + // To support printers that do not implement `PrettyPrinter`, a `Vec` or + // linked list on the stack would need to be built, before any printing. + match self.try_print_visible_def_path(visible_parent)? { + (cx, false) => return Ok((cx, false)), + (cx, true) => self = cx, + } + let actual_parent = self.tcx().parent(def_id); debug!( "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", visible_parent, actual_parent, @@ -403,7 +354,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // have access to the re-exported name. DefPathData::Module(actual_name) | DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - self.tcx.item_children(visible_parent) + self.tcx().item_children(visible_parent) .iter() .find(|child| child.def.def_id() == def_id) .map(|child| child.ident.as_str()) @@ -413,7 +364,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { // Re-exported `extern crate` (#43189). if let DefPathData::CrateRoot = data { - self.tcx.original_crate_name(def_id.krate).as_str() + self.tcx().original_crate_name(def_id.krate).as_str() } else { Symbol::intern("").as_str() } @@ -421,14 +372,14 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }, }; debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok((self.path_append(|cx| cx.ok(), &symbol)?, true)) + Ok((self.path_append(Ok, &symbol)?, true)) } - pub fn pretty_path_qualified( + fn pretty_path_qualified( self, self_ty: Ty<'tcx>, trait_ref: Option>, - ) -> Result { + ) -> Result { if trait_ref.is_none() { // Inherent impls. Try to print `Foo::bar` for an inherent // impl on `Foo`, but fallback to `::bar` if self-type is @@ -451,19 +402,17 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { if let Some(trait_ref) = trait_ref { p!(write(" as "), print(trait_ref)); } - cx.ok() + Ok(cx) }) } - pub fn pretty_path_append_impl( + fn pretty_path_append_impl( mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, - ) -> Result { - self = PrintCx::new(self.tcx, print_prefix(self)?); + ) -> Result { + self = print_prefix(self)?; self.generic_delimiters(|mut cx| { define_scoped_cx!(cx); @@ -474,502 +423,78 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(print(self_ty)); - cx.ok() + Ok(cx) }) } -} - -// HACK(eddyb) boxed to avoid moving around a large struct by-value. -pub struct FmtPrinter(Box>); - -pub struct FmtPrinterData { - fmt: F, - - empty_path: bool, - in_value: bool, - - used_region_names: FxHashSet, - region_index: usize, - binder_depth: usize, - - pub region_highlight_mode: RegionHighlightMode, -} - -impl Deref for FmtPrinter { - type Target = FmtPrinterData; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for FmtPrinter { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl FmtPrinter { - pub fn new(fmt: F, ns: Namespace) -> Self { - FmtPrinter(Box::new(FmtPrinterData { - fmt, - empty_path: false, - in_value: ns == Namespace::ValueNS, - used_region_names: Default::default(), - region_index: 0, - binder_depth: 0, - region_highlight_mode: RegionHighlightMode::default(), - })) - } -} - -impl fmt::Write for FmtPrinter { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.fmt.write_str(s) - } -} -impl Printer for FmtPrinter { - type Error = fmt::Error; - - type Path = Self; - type Region = Self; - type Type = Self; - type DynExistential = Self; - - fn print_def_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { + fn pretty_print_type( + mut self, + ty: Ty<'tcx>, + ) -> Result { define_scoped_cx!(self); - // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` - // both here and in `default_print_def_path`. - let generics = substs.map(|_| self.tcx.generics_of(def_id)); - if generics.as_ref().and_then(|g| g.parent).is_none() { - let visible_path_success; - nest!({ - let (path, success) = self.try_print_visible_def_path(def_id)?; - visible_path_success = success; - Ok(path) - }); - if visible_path_success { - return if let (Some(generics), Some(substs)) = (generics, substs) { - let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(|cx| cx.ok(), args) - } else { - self.ok() - }; + match ty.sty { + ty::Bool => p!(write("bool")), + ty::Char => p!(write("char")), + ty::Int(t) => p!(write("{}", t.ty_to_string())), + ty::Uint(t) => p!(write("{}", t.ty_to_string())), + ty::Float(t) => p!(write("{}", t.ty_to_string())), + ty::RawPtr(ref tm) => { + p!(write("*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })); + p!(print(tm.ty)) } - } - - let key = self.tcx.def_key(def_id); - if let DefPathData::Impl = key.disambiguated_data.data { - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = - !def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let span = self.tcx.def_span(def_id); - return self.path_append( - |cx| cx.print_def_path(parent_def_id, None), - &format!("", span), - ); + ty::Ref(r, ty, mutbl) => { + p!(write("&")); + if self.region_should_not_be_omitted(r) { + p!(print(r), write(" ")); + } + p!(print(ty::TypeAndMut { ty, mutbl })) } - } - - self.default_print_def_path(def_id, substs) - } - - fn print_region( - self: PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> Result { - self.pretty_print_region(region) - } - - fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, - ty: Ty<'tcx>, - ) -> Result { - self.pretty_print_type(ty) - } - - fn print_dyn_existential( - self: PrintCx<'_, '_, 'tcx, Self>, - predicates: &'tcx ty::List>, - ) -> Result { - self.pretty_print_dyn_existential(predicates) - } - - fn path_crate( - mut self: PrintCx<'_, '_, '_, Self>, - cnum: CrateNum, - ) -> Result { - self.empty_path = true; - if cnum == LOCAL_CRATE { - if self.tcx.sess.rust_2018() { - // We add the `crate::` keyword on Rust 2018, only when desired. - if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - write!(self, "{}", keywords::Crate.name())?; - self.empty_path = false; + ty::Never => p!(write("!")), + ty::Tuple(ref tys) => { + p!(write("(")); + let mut tys = tys.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty), write(",")); + if let Some(&ty) = tys.next() { + p!(write(" "), print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } } + p!(write(")")) } - } else { - write!(self, "{}", self.tcx.crate_name(cnum))?; - self.empty_path = false; - } - self.ok() - } - fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = self.pretty_path_qualified(self_ty, trait_ref)?; - path.empty_path = false; - Ok(path) - } - - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = self.pretty_path_append_impl(|cx| { - let mut path = print_prefix(cx)?; - if !path.empty_path { - write!(path, "::")?; + ty::FnDef(def_id, substs) => { + let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); + p!(print(sig), write(" {{")); + self = self.print_value_path(def_id, Some(substs))?; + p!(write("}}")) } - - Ok(path) - }, self_ty, trait_ref)?; - path.empty_path = false; - Ok(path) - } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - text: &str, - ) -> Result { - let mut path = print_prefix(self)?; - - // FIXME(eddyb) `text` should never be empty, but it - // currently is for `extern { ... }` "foreign modules". - if !text.is_empty() { - if !path.empty_path { - write!(path, "::")?; + ty::FnPtr(ref bare_fn) => { + p!(print(bare_fn)) } - write!(path, "{}", text)?; - path.empty_path = false; - } - - Ok(path) - } - fn path_generic_args<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - args: &[Kind<'tcx>], - ) -> Result { - define_scoped_cx!(self); - - nest!(print_prefix(self)); + ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Error => p!(write("[type error]")), + ty::Param(ref param_ty) => p!(write("{}", param_ty)), + ty::Bound(debruijn, bound_ty) => { + match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) + } + } - // Don't print `'_` if there's no unerased regions. - let print_regions = args.iter().any(|arg| { - match arg.unpack() { - UnpackedKind::Lifetime(r) => *r != ty::ReErased, - _ => false, + ty::BoundTyKind::Param(p) => p!(write("{}", p)), + } } - }); - let args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - UnpackedKind::Lifetime(_) => print_regions, - _ => true, - } - }); - - if args.clone().next().is_some() { - if self.in_value { - write!(self, "::")?; - } - self.generic_delimiters(|cx| cx.comma_sep(args)) - } else { - self.ok() - } - } -} - -impl PrettyPrinter for FmtPrinter { - fn print_value_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { - let was_in_value = std::mem::replace(&mut self.in_value, true); - let mut path = self.print_def_path(def_id, substs)?; - path.in_value = was_in_value; - - Ok(path) - } - - fn in_binder( - self: PrintCx<'_, '_, 'tcx, Self>, - value: &ty::Binder, - ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> - { - self.pretty_in_binder(value) - } - - fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result { - write!(self, "<")?; - - let was_in_value = std::mem::replace(&mut self.in_value, false); - let mut inner = f(self)?; - inner.in_value = was_in_value; - - write!(inner, ">")?; - Ok(inner) - } - - fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool { - let highlight = self.region_highlight_mode; - if highlight.region_highlighted(region).is_some() { - return true; - } - - if self.tcx.sess.verbose() { - return true; - } - - let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; - - match *region { - ty::ReEarlyBound(ref data) => { - data.name != "" && data.name != "'_" - } - - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - return true; - } - } - - if let Some((region, _)) = highlight.highlight_bound_region { - if br == region { - return true; - } - } - - false - } - - ty::ReScope(_) | - ty::ReVar(_) if identify_regions => true, - - ty::ReVar(_) | - ty::ReScope(_) | - ty::ReErased => false, - - ty::ReStatic | - ty::ReEmpty | - ty::ReClosureBound(_) => true, - } - } -} - -// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. -impl FmtPrinter { - pub fn pretty_print_region( - mut self: PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> Result { - define_scoped_cx!(self); - - // Watch out for region highlights. - let highlight = self.region_highlight_mode; - if let Some(n) = highlight.region_highlighted(region) { - p!(write("'{}", n)); - return self.ok(); - } - - if self.tcx.sess.verbose() { - p!(write("{:?}", region)); - return self.ok(); - } - - let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *region { - ty::ReEarlyBound(ref data) => { - if data.name != "" { - p!(write("{}", data.name)); - return self.ok(); - } - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - p!(write("{}", name)); - return self.ok(); - } - } - - if let Some((region, counter)) = highlight.highlight_bound_region { - if br == region { - p!(write("'{}", counter)); - return self.ok(); - } - } - } - ty::ReScope(scope) if identify_regions => { - match scope.data { - region::ScopeData::Node => - p!(write("'{}s", scope.item_local_id().as_usize())), - region::ScopeData::CallSite => - p!(write("'{}cs", scope.item_local_id().as_usize())), - region::ScopeData::Arguments => - p!(write("'{}as", scope.item_local_id().as_usize())), - region::ScopeData::Destruction => - p!(write("'{}ds", scope.item_local_id().as_usize())), - region::ScopeData::Remainder(first_statement_index) => p!(write( - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - )), - } - return self.ok(); - } - ty::ReVar(region_vid) if identify_regions => { - p!(write("{:?}", region_vid)); - return self.ok(); - } - ty::ReVar(_) => {} - ty::ReScope(_) | - ty::ReErased => {} - ty::ReStatic => { - p!(write("'static")); - return self.ok(); - } - ty::ReEmpty => { - p!(write("'")); - return self.ok(); - } - - // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => { - p!(write("{:?}", vid)); - return self.ok(); - } - } - - p!(write("'_")); - - self.ok() - } -} - -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { - pub fn pretty_print_type( - mut self, - ty: Ty<'tcx>, - ) -> Result { - define_scoped_cx!(self); - - match ty.sty { - ty::Bool => p!(write("bool")), - ty::Char => p!(write("char")), - ty::Int(t) => p!(write("{}", t.ty_to_string())), - ty::Uint(t) => p!(write("{}", t.ty_to_string())), - ty::Float(t) => p!(write("{}", t.ty_to_string())), - ty::RawPtr(ref tm) => { - p!(write("*{} ", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - })); - p!(print(tm.ty)) - } - ty::Ref(r, ty, mutbl) => { - p!(write("&")); - if self.region_should_not_be_omitted(r) { - p!(print(r), write(" ")); - } - p!(print(ty::TypeAndMut { ty, mutbl })) - } - ty::Never => p!(write("!")), - ty::Tuple(ref tys) => { - p!(write("(")); - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - p!(print(ty), write(",")); - if let Some(&ty) = tys.next() { - p!(write(" "), print(ty)); - for &ty in tys { - p!(write(", "), print(ty)); - } - } - } - p!(write(")")) - } - ty::FnDef(def_id, substs) => { - let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); - p!(print(sig), write(" {{")); - nest!(self.print_value_path(def_id, Some(substs))); - p!(write("}}")) - } - ty::FnPtr(ref bare_fn) => { - p!(print(bare_fn)) - } - ty::Infer(infer_ty) => p!(write("{}", infer_ty)), - ty::Error => p!(write("[type error]")), - ty::Param(ref param_ty) => p!(write("{}", param_ty)), - ty::Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - p!(write("^{}", bound_ty.var.index())) - } else { - p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) - } - } - - ty::BoundTyKind::Param(p) => p!(write("{}", p)), - } - } - ty::Adt(def, substs) => { - nest!(self.print_def_path(def.did, Some(substs))); + ty::Adt(def, substs) => { + self = self.print_def_path(def.did, Some(substs))?; } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -982,7 +507,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(self.print_def_path(def_id, None)); + self = self.print_def_path(def_id, None)?; } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -993,12 +518,12 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Opaque(def_id, substs) => { // FIXME(eddyb) print this with `print_def_path`. - if self.tcx.sess.verbose() { + if self.tcx().sess.verbose() { p!(write("Opaque({:?}, {:?})", def_id, substs)); - return self.ok(); + return Ok(self); } - let def_key = self.tcx.def_key(def_id); + let def_key = self.tcx().def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { p!(write("{}", name)); let mut substs = substs.iter(); @@ -1011,11 +536,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(write(">")); } - return self.ok(); + return Ok(self); } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); + let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs); let mut first = true; let mut is_sized = false; @@ -1023,7 +548,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { is_sized = true; continue; } @@ -1042,8 +567,8 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Str => p!(write("str")), ty::Generator(did, substs, movability) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); - let witness = substs.witness(did, self.tcx); + let upvar_tys = substs.upvar_tys(did, self.tcx()); + let witness = substs.witness(did, self.tcx()); if movability == hir::GeneratorMovability::Movable { p!(write("[generator")); } else { @@ -1051,10 +576,10 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) + for (freevar, upvar_ty) in self.tcx().freevars(did) .as_ref() .map_or(&[][..], |fv| &fv[..]) .iter() @@ -1063,7 +588,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!( write("{}{}:", sep, - self.tcx.hir().name(freevar.var_id())), + self.tcx().hir().name(freevar.var_id())), print(upvar_ty)); sep = ", "; } @@ -1083,21 +608,21 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" "), print(witness), write("]")) }, ty::GeneratorWitness(types) => { - nest!(self.in_binder(&types)) + self = self.in_binder(&types)?; } ty::Closure(did, substs) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); + let upvar_tys = substs.upvar_tys(did, self.tcx()); p!(write("[closure")); // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - if self.tcx.sess.opts.debugging_opts.span_free_formats { + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + if self.tcx().sess.opts.debugging_opts.span_free_formats { p!(write("@{:?}", hir_id)); } else { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); } let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) + for (freevar, upvar_ty) in self.tcx().freevars(did) .as_ref() .map_or(&[][..], |fv| &fv[..]) .iter() @@ -1106,7 +631,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!( write("{}{}:", sep, - self.tcx.hir().name(freevar.var_id())), + self.tcx().hir().name(freevar.var_id())), print(upvar_ty)); sep = ", "; } @@ -1123,11 +648,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - if self.tcx.sess.verbose() { + if self.tcx().sess.verbose() { p!(write( " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, self.tcx), - substs.closure_sig_ty(did, self.tcx) + substs.closure_kind_ty(did, self.tcx()), + substs.closure_sig_ty(did, self.tcx()) )); } @@ -1144,7 +669,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ConstValue::Infer(..) => p!(write("_")), ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), - _ => p!(write("{}", c.unwrap_usize(self.tcx))), + _ => p!(write("{}", c.unwrap_usize(self.tcx()))), } } } @@ -1155,30 +680,30 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - self.ok() + Ok(self) } fn pretty_print_dyn_existential( mut self, predicates: &'tcx ty::List>, - ) -> Result { + ) -> Result { define_scoped_cx!(self); // Generate the main trait ref, including associated types. let mut first = true; if let Some(principal) = predicates.principal() { - nest!(self.print_def_path(principal.def_id, None)); + self = self.print_def_path(principal.def_id, None)?; let mut resugared = false; // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(principal.def_id); - if !self.tcx.sess.verbose() && fn_trait_kind.is_some() { + let fn_trait_kind = self.tcx().lang_items().fn_trait_kind(principal.def_id); + if !self.tcx().sess.verbose() && fn_trait_kind.is_some() { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = predicates.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(self.pretty_fn_sig(args, false, proj.ty)); + self = self.pretty_fn_sig(args, false, proj.ty)?; resugared = true; } } @@ -1188,11 +713,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // in order to place the projections inside the `<...>`. if !resugared { // Use a type that can't appear in defaults of type parameters. - let dummy_self = self.tcx.mk_infer(ty::FreshTy(0)); - let principal = principal.with_self_ty(self.tcx, dummy_self); + let dummy_self = self.tcx().mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(self.tcx(), dummy_self); let args = self.generic_args_to_print( - self.tcx.generics_of(principal.def_id), + self.tcx().generics_of(principal.def_id), principal.substs, ); @@ -1217,13 +742,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let args = arg0.into_iter().chain(args); let projections = projection0.into_iter().chain(projections); - nest!(self.generic_delimiters(|mut cx| { - cx = PrintCx::new(cx.tcx, cx.comma_sep(args)?); + self = self.generic_delimiters(|mut cx| { + cx = cx.comma_sep(args)?; if arg0.is_some() && projection0.is_some() { write!(cx, ", ")?; } cx.comma_sep(projections) - })); + })?; } } first = false; @@ -1233,7 +758,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // FIXME(eddyb) avoid printing twice (needed to ensure // that the auto traits are sorted *and* printed via cx). let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { - (self.tcx.def_path_str(did), did) + (self.tcx().def_path_str(did), did) }).collect(); // The auto traits come ordered by `DefPathHash`. While @@ -1251,18 +776,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } first = false; - nest!(self.print_def_path(def_id, None)); + self = self.print_def_path(def_id, None)?; } - self.ok() + Ok(self) } - pub fn pretty_fn_sig( + fn pretty_fn_sig( mut self, inputs: &[Ty<'tcx>], c_variadic: bool, output: Ty<'tcx>, - ) -> Result { + ) -> Result { define_scoped_cx!(self); p!(write("(")); @@ -1281,30 +806,476 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" -> "), print(output)); } - self.ok() + Ok(self) } } -// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, -// `region_index` and `used_region_names`. -impl FmtPrinter { - pub fn pretty_in_binder( - mut self: PrintCx<'_, '_, 'tcx, Self>, - value: &ty::Binder, - ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> - { - fn name_by_region_index(index: usize) -> InternedString { - match index { - 0 => Symbol::intern("'r"), - 1 => Symbol::intern("'s"), - i => Symbol::intern(&format!("'t{}", i-2)), - }.as_interned_str() - } +// HACK(eddyb) boxed to avoid moving around a large struct by-value. +pub struct FmtPrinter<'a, 'gcx, 'tcx, F>(Box>); - // Replace any anonymous late-bound regions with named - // variants, using gensym'd identifiers, so that we can - // clearly differentiate between named and unnamed regions in +pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + fmt: F, + + empty_path: bool, + in_value: bool, + + used_region_names: FxHashSet, + region_index: usize, + binder_depth: usize, + + pub region_highlight_mode: RegionHighlightMode, +} + +impl Deref for FmtPrinter<'a, 'gcx, 'tcx, F> { + type Target = FmtPrinterData<'a, 'gcx, 'tcx, F>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for FmtPrinter<'_, '_, '_, F> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl FmtPrinter<'a, 'gcx, 'tcx, F> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fmt: F, ns: Namespace) -> Self { + FmtPrinter(Box::new(FmtPrinterData { + tcx, + fmt, + empty_path: false, + in_value: ns == Namespace::ValueNS, + used_region_names: Default::default(), + region_index: 0, + binder_depth: 0, + region_highlight_mode: RegionHighlightMode::default(), + })) + } +} + +impl TyCtxt<'_, '_, '_> { + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ConstParam(..) | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. + pub fn def_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); + let mut s = String::new(); + let _ = FmtPrinter::new(self, &mut s, ns) + .print_def_path(def_id, None); + s + } +} + +impl fmt::Write for FmtPrinter<'_, '_, '_, F> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.fmt.write_str(s) + } +} + +impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + type Error = fmt::Error; + + type Path = Self; + type Region = Self; + type Type = Self; + type DynExistential = Self; + + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + + fn print_def_path( + mut self, + def_id: DefId, + substs: Option>, + ) -> Result { + define_scoped_cx!(self); + + // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` + // both here and in `default_print_def_path`. + let generics = substs.map(|_| self.tcx.generics_of(def_id)); + if generics.as_ref().and_then(|g| g.parent).is_none() { + match self.try_print_visible_def_path(def_id)? { + (cx, true) => return if let (Some(generics), Some(substs)) = (generics, substs) { + let args = cx.generic_args_to_print(generics, substs); + cx.path_generic_args(Ok, args) + } else { + Ok(cx) + }, + (cx, false) => self = cx, + } + } + + let key = self.tcx.def_key(def_id); + if let DefPathData::Impl = key.disambiguated_data.data { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = + !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let span = self.tcx.def_span(def_id); + return self.path_append( + |cx| cx.print_def_path(parent_def_id, None), + &format!("", span), + ); + } + } + + self.default_print_def_path(def_id, substs) + } + + fn print_region( + self, + region: ty::Region<'_>, + ) -> Result { + self.pretty_print_region(region) + } + + fn print_type( + self, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + + fn print_dyn_existential( + self, + predicates: &'tcx ty::List>, + ) -> Result { + self.pretty_print_dyn_existential(predicates) + } + + fn path_crate( + mut self, + cnum: CrateNum, + ) -> Result { + self.empty_path = true; + if cnum == LOCAL_CRATE { + if self.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + write!(self, "{}", keywords::Crate.name())?; + self.empty_path = false; + } + } + } else { + write!(self, "{}", self.tcx.crate_name(cnum))?; + self.empty_path = false; + } + Ok(self) + } + fn path_qualified( + mut self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_qualified(self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + + fn path_append_impl( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_append_impl(|mut cx| { + cx = print_prefix(cx)?; + if !cx.empty_path { + write!(cx, "::")?; + } + + Ok(cx) + }, self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + text: &str, + ) -> Result { + self = print_prefix(self)?; + + // FIXME(eddyb) `text` should never be empty, but it + // currently is for `extern { ... }` "foreign modules". + if !text.is_empty() { + if !self.empty_path { + write!(self, "::")?; + } + write!(self, "{}", text)?; + self.empty_path = false; + } + + Ok(self) + } + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + args: &[Kind<'tcx>], + ) -> Result { + self = print_prefix(self)?; + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + + if args.clone().next().is_some() { + if self.in_value { + write!(self, "::")?; + } + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + Ok(self) + } + } +} + +impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + fn print_value_path( + mut self, + def_id: DefId, + substs: Option>, + ) -> Result { + let was_in_value = std::mem::replace(&mut self.in_value, true); + self = self.print_def_path(def_id, substs)?; + self.in_value = was_in_value; + + Ok(self) + } + + fn in_binder( + self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + self.pretty_in_binder(value) + } + + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, + ) -> Result { + write!(self, "<")?; + + let was_in_value = std::mem::replace(&mut self.in_value, false); + let mut inner = f(self)?; + inner.in_value = was_in_value; + + write!(inner, ">")?; + Ok(inner) + } + + fn region_should_not_be_omitted( + &self, + region: ty::Region<'_>, + ) -> bool { + let highlight = self.region_highlight_mode; + if highlight.region_highlighted(region).is_some() { + return true; + } + + if self.tcx.sess.verbose() { + return true; + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + match *region { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } + + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } + + ty::ReScope(_) | + ty::ReVar(_) if identify_regions => true, + + ty::ReVar(_) | + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. +impl FmtPrinter<'_, '_, '_, F> { + pub fn pretty_print_region( + mut self, + region: ty::Region<'_>, + ) -> Result { + define_scoped_cx!(self); + + // Watch out for region highlights. + let highlight = self.region_highlight_mode; + if let Some(n) = highlight.region_highlighted(region) { + p!(write("'{}", n)); + return Ok(self); + } + + if self.tcx.sess.verbose() { + p!(write("{:?}", region)); + return Ok(self); + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *region { + ty::ReEarlyBound(ref data) => { + if data.name != "" { + p!(write("{}", data.name)); + return Ok(self); + } + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + p!(write("{}", name)); + return Ok(self); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + p!(write("'{}", counter)); + return Ok(self); + } + } + } + ty::ReScope(scope) if identify_regions => { + match scope.data { + region::ScopeData::Node => + p!(write("'{}s", scope.item_local_id().as_usize())), + region::ScopeData::CallSite => + p!(write("'{}cs", scope.item_local_id().as_usize())), + region::ScopeData::Arguments => + p!(write("'{}as", scope.item_local_id().as_usize())), + region::ScopeData::Destruction => + p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => p!(write( + "'{}_{}rs", + scope.item_local_id().as_usize(), + first_statement_index.index() + )), + } + return Ok(self); + } + ty::ReVar(region_vid) if identify_regions => { + p!(write("{:?}", region_vid)); + return Ok(self); + } + ty::ReVar(_) => {} + ty::ReScope(_) | + ty::ReErased => {} + ty::ReStatic => { + p!(write("'static")); + return Ok(self); + } + ty::ReEmpty => { + p!(write("'")); + return Ok(self); + } + + // The user should never encounter these in unsubstituted form. + ty::ReClosureBound(vid) => { + p!(write("{:?}", vid)); + return Ok(self); + } + } + + p!(write("'_")); + + Ok(self) + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, +// `region_index` and `used_region_names`. +impl FmtPrinter<'_, 'gcx, 'tcx, F> { + pub fn pretty_in_binder( + mut self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> + { + fn name_by_region_index(index: usize) -> InternedString { + match index { + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), + }.as_interned_str() + } + + // Replace any anonymous late-bound regions with named + // variants, using gensym'd identifiers, so that we can + // clearly differentiate between named and unnamed regions in // the output. We'll probably want to tweak this over time to // decide just how much information to give. if self.binder_depth == 0 { @@ -1382,107 +1353,94 @@ impl FmtPrinter { } } -impl Print<'tcx, P> for ty::Binder - where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> +impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::Binder + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> { type Output = P; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.in_binder(self) } } -pub trait LiftAndPrintToFmt<'tcx> { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result; -} - -impl LiftAndPrintToFmt<'tcx> for T - where T: ty::Lift<'tcx>, - for<'a, 'b> >::Lifted: - Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error> +impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::OutlivesPredicate + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, + U: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - tcx.lift(self) - .expect("could not lift for printing") - .print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; - Ok(()) - } -} - -// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. -impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - self.print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; - Ok(()) + type Output = P; + type Error = P::Error; + fn print(&self, mut cx: P) -> Result { + define_scoped_cx!(cx); + p!(print(self.0), write(" : "), print(self.1)); + Ok(cx) } } macro_rules! forward_display_to_print { - (<$($T:ident),*> $ty:ty) => { - impl<$($T),*> fmt::Display for $ty - where Self: for<'a> LiftAndPrintToFmt<'a> - { + ($($ty:ty),+) => { + $(impl fmt::Display for $ty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f)) + ty::tls::with(|tcx| { + tcx.lift(self) + .expect("could not lift for printing") + .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) } - } - }; - - ($ty:ty) => { - forward_display_to_print!(<> $ty); + })+ }; } macro_rules! define_print_and_forward_display { - (($self:ident, $cx:ident): <$($T:ident),*> $ty:ty $print:block) => { - impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $ty - where $($T: Print<'tcx, P, Output = P, Error = P::Error>),* - { + (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { + $(impl<'gcx: 'tcx, 'tcx, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for $ty { type Output = P; type Error = fmt::Error; - fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&$self, $cx: P) -> Result { #[allow(unused_mut)] let mut $cx = $cx; define_scoped_cx!($cx); let _: () = $print; #[allow(unreachable_code)] - $cx.ok() + Ok($cx) } - } + })+ - forward_display_to_print!(<$($T),*> $ty); - }; - - (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { - $(define_print_and_forward_display!(($self, $cx): <> $ty $print);)+ + forward_display_to_print!($($ty),+); }; } -forward_display_to_print!(ty::RegionKind); -forward_display_to_print!(Ty<'tcx>); -forward_display_to_print!(&'tcx ty::List>); -forward_display_to_print!( ty::Binder); - -define_print_and_forward_display! { - (self, cx): - - ty::OutlivesPredicate { - p!(print(self.0), write(" : "), print(self.1)) +// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. +impl fmt::Display for ty::RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) } } +forward_display_to_print! { + Ty<'tcx>, + &'tcx ty::List>, + + // HACK(eddyb) these are exhaustive instead of generic, + // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet. + ty::Binder<&'tcx ty::List>>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder, ty::Region<'tcx>>>, + ty::Binder, ty::Region<'tcx>>>, + + ty::OutlivesPredicate, ty::Region<'tcx>>, + ty::OutlivesPredicate, ty::Region<'tcx>> +} + define_print_and_forward_display! { (self, cx): @@ -1505,13 +1463,13 @@ define_print_and_forward_display! { ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = self.with_self_ty(cx.tcx, dummy_self); + let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0)); + let trait_ref = self.with_self_ty(cx.tcx(), dummy_self); p!(print(trait_ref)) } ty::ExistentialProjection<'tcx> { - let name = cx.tcx.associated_item(self.item_def_id).ident; + let name = cx.tcx().associated_item(self.item_def_id).ident; p!(write("{}=", name), print(self.ty)) } @@ -1520,7 +1478,7 @@ define_print_and_forward_display! { ty::ExistentialPredicate::Trait(x) => p!(print(x)), ty::ExistentialPredicate::Projection(x) => p!(print(x)), ty::ExistentialPredicate::AutoTrait(def_id) => { - nest!(cx.print_def_path(def_id, None)) + cx = cx.print_def_path(def_id, None)?; } } } @@ -1535,13 +1493,13 @@ define_print_and_forward_display! { } p!(write("fn")); - nest!(cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + cx = cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())?; } ty::InferTy { - if cx.tcx.sess.verbose() { + if cx.tcx().sess.verbose() { p!(write("{:?}", self)); - return cx.ok(); + return Ok(cx); } match *self { ty::TyVar(_) => p!(write("_")), @@ -1554,7 +1512,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - nest!(cx.print_def_path(self.def_id, Some(self.substs))); + cx = cx.print_def_path(self.def_id, Some(self.substs))?; } ConstValue<'tcx> { @@ -1569,7 +1527,7 @@ define_print_and_forward_display! { p!(write("{} : {}", self.val, self.ty)) } - ty::LazyConst<'tcx> { + &'tcx ty::LazyConst<'tcx> { match self { // FIXME(const_generics) this should print at least the type. ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), @@ -1598,7 +1556,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - nest!(cx.print_def_path(self.item_def_id, Some(self.substs))); + cx = cx.print_def_path(self.item_def_id, Some(self.substs))?; } ty::ClosureKind { @@ -1619,17 +1577,17 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(cx.print_def_path(trait_def_id, None)); + cx = cx.print_def_path(trait_def_id, None)?; p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `")); - nest!(cx.print_value_path(closure_def_id, None)); + cx = cx.print_value_path(closure_def_id, None)?; p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `")); - nest!(cx.print_value_path(def_id, Some(substs))); + cx = cx.print_value_path(def_id, Some(substs))?; p!(write("` can be evaluated")) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 32a39c2eb883d..4cbb315cefadb 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -8,7 +8,7 @@ use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::print::{FmtPrinter, PrintCx, Printer}; +use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use smallvec::SmallVec; use crate::mir::interpret; @@ -34,8 +34,9 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.def_id, None)?; + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.def_id, None)?; Ok(()) }) } @@ -43,8 +44,9 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.did, None)?; + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.did, None)?; Ok(()) }) } @@ -333,6 +335,7 @@ CloneTypeFoldableAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations +// FIXME(eddyb) replace all the uses of `Option::map` with `?`. impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { type Lifted = (A::Lifted, B::Lifted); fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { @@ -429,6 +432,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { } } +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { + type Lifted = ty::ExistentialPredicate<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + match self { + ty::ExistentialPredicate::Trait(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Trait) + } + ty::ExistentialPredicate::Projection(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Projection) + } + ty::ExistentialPredicate::AutoTrait(def_id) => { + Some(ty::ExistentialPredicate::AutoTrait(*def_id)) + } + } + } +} + impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { type Lifted = ty::TraitPredicate<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 084b86b1eb424..d1fcc88e59900 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -92,7 +92,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::print::{PrettyPrinter, PrintCx, Printer, Print}; +use rustc::ty::print::{PrettyPrinter, Printer, Print}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -223,10 +223,11 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - PrintCx::new(tcx, SymbolPath::new(tcx)) - .print_def_path(def_id, None) - .unwrap() - .into_interned() + SymbolPrinter { + tcx, + path: SymbolPath::new(), + keep_within_component: false, + }.print_def_path(def_id, None).unwrap().path.into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -318,13 +319,17 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPath::from_interned(tcx.def_symbol_name(def_id), tcx); + let mut printer = SymbolPrinter { + tcx, + path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)), + keep_within_component: false, + }; if instance.is_vtable_shim() { - let _ = buf.write_str("{{vtable-shim}}"); + let _ = printer.write_str("{{vtable-shim}}"); } - buf.finish(hash) + printer.path.finish(hash) } // Follow C++ namespace-mangling style, see @@ -344,33 +349,22 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance struct SymbolPath { result: String, temp_buf: String, - strict_naming: bool, - - // When `true`, `finalize_pending_component` isn't used. - // This is needed when recursing into `path_qualified`, - // or `path_generic_args`, as any nested paths are - // logically within one component. - keep_within_component: bool, } impl SymbolPath { - fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { + fn new() -> Self { let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), - keep_within_component: false, }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { + fn from_interned(symbol: ty::SymbolName) -> Self { let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), - keep_within_component: false, }; result.result.push_str(&symbol.as_str()); result @@ -398,11 +392,22 @@ impl SymbolPath { } } +struct SymbolPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + path: SymbolPath, + + // When `true`, `finalize_pending_component` isn't used. + // This is needed when recursing into `path_qualified`, + // or `path_generic_args`, as any nested paths are + // logically within one component. + keep_within_component: bool, +} + // HACK(eddyb) this relies on using the `fmt` interface to get // `PrettyPrinter` aka pretty printing of e.g. types in paths, // symbol names should have their own printing machinery. -impl Printer for SymbolPath { +impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { type Error = fmt::Error; type Path = Self; @@ -410,15 +415,19 @@ impl Printer for SymbolPath { type Type = Self; type DynExistential = Self; + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { - self.ok() + Ok(self) } fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, ty: Ty<'tcx>, ) -> Result { match ty.sty { @@ -436,7 +445,7 @@ impl Printer for SymbolPath { } fn print_dyn_existential( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, predicates: &'tcx ty::List>, ) -> Result { let mut first = false; @@ -445,20 +454,20 @@ impl Printer for SymbolPath { write!(self, "+")?; } first = false; - self = PrintCx::new(self.tcx, p.print(self)?); + self = p.print(self)?; } - self.ok() + Ok(self) } fn path_crate( - mut self: PrintCx<'_, '_, '_, Self>, + mut self, cnum: CrateNum, ) -> Result { self.write_str(&self.tcx.original_crate_name(cnum).as_str())?; - self.ok() + Ok(self) } fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -480,11 +489,9 @@ impl Printer for SymbolPath { } } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -494,33 +501,29 @@ impl Printer for SymbolPath { trait_ref, ) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { - let mut path = print_prefix(self)?; + self = print_prefix(self)?; - if path.keep_within_component { + if self.keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. - path.write_str("::")?; + self.write_str("::")?; } else { - path.finalize_pending_component(); + self.path.finalize_pending_component(); } - path.write_str(text)?; - Ok(path) + self.write_str(text)?; + Ok(self) } - fn path_generic_args<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, args: &[Kind<'tcx>], ) -> Result { - self = PrintCx::new(self.tcx, print_prefix(self)?); + self = print_prefix(self)?; let args = args.iter().cloned().filter(|arg| { match arg.unpack() { @@ -532,52 +535,52 @@ impl Printer for SymbolPath { if args.clone().next().is_some() { self.generic_delimiters(|cx| cx.comma_sep(args)) } else { - self.ok() + Ok(self) } } } -impl PrettyPrinter for SymbolPath { +impl PrettyPrinter<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, + &self, _region: ty::Region<'_>, ) -> bool { false } fn comma_sep( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, mut elems: impl Iterator, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error> { if let Some(first) = elems.next() { - self = PrintCx::new(self.tcx, first.print(self)?); + self = first.print(self)?; for elem in elems { self.write_str(",")?; - self = PrintCx::new(self.tcx, elem.print(self)?); + self = elem.print(self)?; } } - self.ok() + Ok(self) } - fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, ) -> Result { write!(self, "<")?; let kept_within_component = mem::replace(&mut self.keep_within_component, true); - let mut path = f(self)?; - path.keep_within_component = kept_within_component; + self = f(self)?; + self.keep_within_component = kept_within_component; - write!(path, ">")?; + write!(self, ">")?; - Ok(path) + Ok(self) } } -impl fmt::Write for SymbolPath { +impl fmt::Write for SymbolPrinter<'_, '_> { fn write_str(&mut self, s: &str) -> fmt::Result { // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! @@ -586,45 +589,45 @@ impl fmt::Write for SymbolPath { // are replaced with '$' there. for c in s.chars() { - if self.temp_buf.is_empty() { + if self.path.temp_buf.is_empty() { match c { 'a'..='z' | 'A'..='Z' | '_' => {} _ => { // Underscore-qualify anything that didn't start as an ident. - self.temp_buf.push('_'); + self.path.temp_buf.push('_'); } } } match c { // Escape these with $ sequences - '@' => self.temp_buf.push_str("$SP$"), - '*' => self.temp_buf.push_str("$BP$"), - '&' => self.temp_buf.push_str("$RF$"), - '<' => self.temp_buf.push_str("$LT$"), - '>' => self.temp_buf.push_str("$GT$"), - '(' => self.temp_buf.push_str("$LP$"), - ')' => self.temp_buf.push_str("$RP$"), - ',' => self.temp_buf.push_str("$C$"), - - '-' | ':' | '.' if self.strict_naming => { + '@' => self.path.temp_buf.push_str("$SP$"), + '*' => self.path.temp_buf.push_str("$BP$"), + '&' => self.path.temp_buf.push_str("$RF$"), + '<' => self.path.temp_buf.push_str("$LT$"), + '>' => self.path.temp_buf.push_str("$GT$"), + '(' => self.path.temp_buf.push_str("$LP$"), + ')' => self.path.temp_buf.push_str("$RP$"), + ',' => self.path.temp_buf.push_str("$C$"), + + '-' | ':' | '.' if self.tcx.has_strict_asm_symbol_naming() => { // NVPTX doesn't support these characters in symbol names. - self.temp_buf.push('$') + self.path.temp_buf.push('$') } // '.' doesn't occur in types and functions, so reuse it // for ':' and '-' - '-' | ':' => self.temp_buf.push('.'), + '-' | ':' => self.path.temp_buf.push('.'), // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.temp_buf.push(c), + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c), _ => { - self.temp_buf.push('$'); + self.path.temp_buf.push('$'); for c in c.escape_unicode().skip(1) { match c { '{' => {} - '}' => self.temp_buf.push('$'), - c => self.temp_buf.push(c), + '}' => self.path.temp_buf.push('$'), + c => self.path.temp_buf.push(c), } } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index d7dd0313e9487..8613464732457 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -2326,7 +2326,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// name where required. fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); // We need to add synthesized lifetimes where appropriate. We do // this by hooking into the pretty printer and telling it to label the @@ -2341,7 +2341,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => {} } - let _ = ty.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); + let _ = ty.print(printer); s } @@ -2349,7 +2349,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// synthesized lifetime name where required. fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); let region = match ty.sty { ty::TyKind::Ref(region, _, _) => { @@ -2366,7 +2366,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => bug!("ty for annotation of borrow region is not a reference"), }; - let _ = region.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); + let _ = region.print(printer); s } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6822de2bcebae..53087eb1b1aba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4223,13 +4223,18 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { } } -pub fn get_path_for_type(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path -where F: Fn(DefId) -> Def { - use rustc::ty::print::{PrintCx, Printer}; +pub fn get_path_for_type( + tcx: TyCtxt<'_, '_, '_>, + def_id: DefId, + def_ctor: impl Fn(DefId) -> Def, +) -> hir::Path { + use rustc::ty::print::Printer; - struct AbsolutePathPrinter; + struct AbsolutePathPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + } - impl Printer for AbsolutePathPrinter { + impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { type Error = !; type Path = Vec; @@ -4237,35 +4242,39 @@ where F: Fn(DefId) -> Def { type Type = (); type DynExistential = (); + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { Ok(()) } fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, _ty: Ty<'tcx>, ) -> Result { Ok(()) } - fn print_dyn_existential<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_dyn_existential( + self, _predicates: &'tcx ty::List>, ) -> Result { Ok(()) } fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -4276,11 +4285,9 @@ where F: Fn(DefId) -> Def { }]) } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -4296,29 +4303,25 @@ where F: Fn(DefId) -> Def { Ok(path) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } } - let names = PrintCx::new(tcx, AbsolutePathPrinter) + let names = AbsolutePathPrinter { tcx: tcx.global_tcx() } .print_def_path(def_id, None) .unwrap(); From 9df7c3f48fd4bb20da04624d19c8c1465d1117dc Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 25 Jan 2019 12:28:43 +0200 Subject: [PATCH 144/157] rustc: let ty::print::pretty's p! macro call arbitrary methods. --- src/librustc/ty/print/pretty.rs | 67 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index fff4ca822d20e..bc98aee233a34 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -19,20 +19,19 @@ use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. use super::*; -macro_rules! print_inner { - (write ($($data:expr),+)) => { +macro_rules! p { + (@write($($data:expr),+)) => { write!(scoped_cx!(), $($data),+)? }; - ($kind:ident ($data:expr)) => { - scoped_cx!() = $data.$kind(scoped_cx!())? + (@print($x:expr)) => { + scoped_cx!() = $x.print(scoped_cx!())? }; -} -macro_rules! p { - ($($kind:ident $data:tt),+) => { - { - $(print_inner!($kind $data));+ - } + (@$method:ident($($arg:expr),*)) => { + scoped_cx!() = scoped_cx!().$method($($arg),*)? }; + ($($kind:ident $data:tt),+) => {{ + $(p!(@$kind $data);)+ + }}; } macro_rules! define_scoped_cx { ($cx:ident) => { @@ -470,9 +469,8 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } ty::FnDef(def_id, substs) => { let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); - p!(print(sig), write(" {{")); - self = self.print_value_path(def_id, Some(substs))?; - p!(write("}}")) + p!(print(sig), + write(" {{"), print_value_path(def_id, Some(substs)), write("}}")); } ty::FnPtr(ref bare_fn) => { p!(print(bare_fn)) @@ -494,7 +492,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } } ty::Adt(def, substs) => { - self = self.print_def_path(def.did, Some(substs))?; + p!(print_def_path(def.did, Some(substs))); } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -507,7 +505,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } } ty::Foreign(def_id) => { - self = self.print_def_path(def_id, None)?; + p!(print_def_path(def_id, None)); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -608,7 +606,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: p!(write(" "), print(witness), write("]")) }, ty::GeneratorWitness(types) => { - self = self.in_binder(&types)?; + p!(in_binder(&types)); } ty::Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, self.tcx()); @@ -693,7 +691,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: let mut first = true; if let Some(principal) = predicates.principal() { - self = self.print_def_path(principal.def_id, None)?; + p!(print_def_path(principal.def_id, None)); let mut resugared = false; @@ -703,7 +701,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = predicates.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - self = self.pretty_fn_sig(args, false, proj.ty)?; + p!(pretty_fn_sig(args, false, proj.ty)); resugared = true; } } @@ -742,13 +740,13 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: let args = arg0.into_iter().chain(args); let projections = projection0.into_iter().chain(projections); - self = self.generic_delimiters(|mut cx| { + p!(generic_delimiters(|mut cx| { cx = cx.comma_sep(args)?; if arg0.is_some() && projection0.is_some() { write!(cx, ", ")?; } cx.comma_sep(projections) - })?; + })); } } first = false; @@ -776,7 +774,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } first = false; - self = self.print_def_path(def_id, None)?; + p!(print_def_path(def_id, None)); } Ok(self) @@ -1478,7 +1476,7 @@ define_print_and_forward_display! { ty::ExistentialPredicate::Trait(x) => p!(print(x)), ty::ExistentialPredicate::Projection(x) => p!(print(x)), ty::ExistentialPredicate::AutoTrait(def_id) => { - cx = cx.print_def_path(def_id, None)?; + p!(print_def_path(def_id, None)); } } } @@ -1492,8 +1490,7 @@ define_print_and_forward_display! { p!(write("extern {} ", self.abi)); } - p!(write("fn")); - cx = cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())?; + p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } ty::InferTy { @@ -1512,7 +1509,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - cx = cx.print_def_path(self.def_id, Some(self.substs))?; + p!(print_def_path(self.def_id, Some(self.substs))); } ConstValue<'tcx> { @@ -1556,7 +1553,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - cx = cx.print_def_path(self.item_def_id, Some(self.substs))?; + p!(print_def_path(self.item_def_id, Some(self.substs))); } ty::ClosureKind { @@ -1576,19 +1573,19 @@ define_print_and_forward_display! { ty::Predicate::Projection(ref predicate) => p!(print(predicate)), ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { - p!(write("the trait `")); - cx = cx.print_def_path(trait_def_id, None)?; - p!(write("` is object-safe")) + p!(write("the trait `"), + print_def_path(trait_def_id, None), + write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!(write("the closure `")); - cx = cx.print_value_path(closure_def_id, None)?; - p!(write("` implements the trait `{}`", kind)) + p!(write("the closure `"), + print_value_path(closure_def_id, None), + write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - p!(write("the constant `")); - cx = cx.print_value_path(def_id, Some(substs))?; - p!(write("` can be evaluated")) + p!(write("the constant `"), + print_value_path(def_id, Some(substs)), + write("` can be evaluated")) } } } From 8619edede1496a8d9c4131f9cb2079e71dccd5fb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 29 Jan 2019 07:21:11 +0200 Subject: [PATCH 145/157] rustc: slice substs in ty::print instead of passing the full ones. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/instance.rs | 2 +- src/librustc/ty/print/mod.rs | 96 +++++++++++----------- src/librustc/ty/print/pretty.rs | 49 +++++------ src/librustc/ty/structural_impls.rs | 4 +- src/librustc_codegen_utils/symbol_names.rs | 4 +- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/test/ui/namespace/namespace-mix.stderr | 4 +- 10 files changed, 79 insertions(+), 88 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 52b4288103813..5026074f5e820 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -533,7 +533,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { AbsolutePathPrinter { tcx: self.tcx } - .print_def_path(def_id, None) + .print_def_path(def_id, &[]) }; // We compare strings because DefPath can be different diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3218f8ea5de48..718b506d05113 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2410,7 +2410,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { ty::tls::with(|tcx| { let substs = tcx.lift(&substs).expect("could not lift for printing"); FmtPrinter::new(tcx, f, Namespace::ValueNS) - .print_def_path(variant_def.did, Some(substs))?; + .print_def_path(variant_def.did, substs)?; Ok(()) })?; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 89d956c8bfae3..995e85fc5f4db 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -179,7 +179,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { ty::tls::with(|tcx| { let substs = tcx.lift(&self.substs).expect("could not lift for printing"); FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS) - .print_def_path(self.def_id(), Some(substs))?; + .print_def_path(self.def_id(), substs)?; Ok(()) })?; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index ad17a8114cabf..c3f4a26a57ee8 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,7 +1,7 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; -use crate::ty::subst::{Kind, Subst, SubstsRef}; +use crate::ty::subst::{Kind, Subst}; use rustc_data_structures::fx::FxHashSet; @@ -29,14 +29,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { fn print_def_path( self, def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], ) -> Result { self.default_print_def_path(def_id, substs) } fn print_impl_path( self, impl_def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -90,7 +90,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { fn default_print_def_path( self, def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); let key = self.tcx().def_key(def_id); @@ -103,61 +103,61 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { } DefPathData::Impl => { + let generics = self.tcx().generics_of(def_id); let mut self_ty = self.tcx().type_of(def_id); - if let Some(substs) = substs { - self_ty = self_ty.subst(self.tcx(), substs); - } - let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); - if let Some(substs) = substs { + if substs.len() >= generics.count() { + self_ty = self_ty.subst(self.tcx(), substs); impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs); } self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } _ => { - let generics = substs.map(|_| self.tcx().generics_of(def_id)); - let generics_parent = generics.as_ref().and_then(|g| g.parent); let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let print_parent_path = |cx: Self| { - if let Some(generics_parent_def_id) = generics_parent { - assert_eq!(parent_def_id, generics_parent_def_id); - - // FIXME(eddyb) try to move this into the parent's printing - // logic, instead of doing it when printing the child. - let parent_generics = cx.tcx().generics_of(parent_def_id); - let parent_has_own_self = - parent_generics.has_self && parent_generics.parent_count == 0; - if let (Some(substs), true) = (substs, parent_has_own_self) { - let trait_ref = ty::TraitRef::new(parent_def_id, substs); - cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) - } else { - cx.print_def_path(parent_def_id, substs) - } - } else { - cx.print_def_path(parent_def_id, None) - } - }; - let print_path = |cx: Self| { + + let mut parent_substs = substs; + let mut trait_qualify_parent = false; + if !substs.is_empty() { + let generics = self.tcx().generics_of(def_id); + parent_substs = &substs[..generics.parent_count.min(substs.len())]; + match key.disambiguated_data.data { - // Skip `::{{constructor}}` on tuple/unit structs. - DefPathData::StructCtor => print_parent_path(cx), - - _ => { - cx.path_append( - print_parent_path, - &key.disambiguated_data.data.as_interned_str().as_str(), - ) + // Closures' own generics are only captures, don't print them. + DefPathData::ClosureExpr => {} + + // If we have any generic arguments to print, we do that + // on top of the same path, but without its own generics. + _ => if !generics.params.is_empty() && substs.len() >= generics.count() { + let args = self.generic_args_to_print(generics, substs); + return self.path_generic_args( + |cx| cx.print_def_path(def_id, parent_substs), + args, + ); } } - }; - if let (Some(generics), Some(substs)) = (generics, substs) { - let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(print_path, args) - } else { - print_path(self) + // FIXME(eddyb) try to move this into the parent's printing + // logic, instead of doing it when printing the child. + trait_qualify_parent = + generics.has_self && + generics.parent == Some(parent_def_id) && + parent_substs.len() == generics.parent_count && + self.tcx().generics_of(parent_def_id).parent_count == 0; } + + self.path_append( + |cx: Self| if trait_qualify_parent { + let trait_ref = ty::TraitRef::new( + parent_def_id, + cx.tcx().intern_substs(parent_substs), + ); + cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) + } else { + cx.print_def_path(parent_def_id, parent_substs) + }, + &key.disambiguated_data.data.as_interned_str().as_str(), + ) } } } @@ -165,7 +165,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { fn generic_args_to_print( &self, generics: &'tcx ty::Generics, - substs: SubstsRef<'tcx>, + substs: &'tcx [Kind<'tcx>], ) -> &'tcx [Kind<'tcx>] { let mut own_params = generics.parent_count..generics.count(); @@ -193,7 +193,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { fn default_print_impl_path( self, impl_def_id: DefId, - _substs: Option>, + _substs: &'tcx [Kind<'tcx>], self_ty: Ty<'tcx>, impl_trait_ref: Option>, ) -> Result { @@ -220,7 +220,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { // trait-type, then fallback to a format that identifies // the module more clearly. self.path_append_impl( - |cx| cx.print_def_path(parent_def_id, None), + |cx| cx.print_def_path(parent_def_id, &[]), self_ty, impl_trait_ref, ) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index bc98aee233a34..54ca63b457af7 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -5,7 +5,7 @@ use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use crate::middle::region; use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; -use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; +use crate::ty::subst::{Kind, Subst, UnpackedKind}; use crate::mir::interpret::ConstValue; use syntax::symbol::{keywords, Symbol}; @@ -178,7 +178,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: fn print_value_path( self, def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], ) -> Result { self.print_def_path(def_id, substs) } @@ -264,7 +264,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok((if !span.is_dummy() { - self.print_def_path(def_id, None)? + self.print_def_path(def_id, &[])? } else { self.path_crate(cnum)? }, true)); @@ -469,8 +469,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } ty::FnDef(def_id, substs) => { let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); - p!(print(sig), - write(" {{"), print_value_path(def_id, Some(substs)), write("}}")); + p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}")); } ty::FnPtr(ref bare_fn) => { p!(print(bare_fn)) @@ -492,7 +491,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } } ty::Adt(def, substs) => { - p!(print_def_path(def.did, Some(substs))); + p!(print_def_path(def.did, substs)); } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -505,7 +504,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } } ty::Foreign(def_id) => { - p!(print_def_path(def_id, None)); + p!(print_def_path(def_id, &[])); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -691,7 +690,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: let mut first = true; if let Some(principal) = predicates.principal() { - p!(print_def_path(principal.def_id, None)); + p!(print_def_path(principal.def_id, &[])); let mut resugared = false; @@ -774,7 +773,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: } first = false; - p!(print_def_path(def_id, None)); + p!(print_def_path(def_id, &[])); } Ok(self) @@ -879,7 +878,7 @@ impl TyCtxt<'_, '_, '_> { debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); let _ = FmtPrinter::new(self, &mut s, ns) - .print_def_path(def_id, None); + .print_def_path(def_id, &[]); s } } @@ -905,21 +904,13 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { fn print_def_path( mut self, def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], ) -> Result { define_scoped_cx!(self); - // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` - // both here and in `default_print_def_path`. - let generics = substs.map(|_| self.tcx.generics_of(def_id)); - if generics.as_ref().and_then(|g| g.parent).is_none() { + if substs.is_empty() { match self.try_print_visible_def_path(def_id)? { - (cx, true) => return if let (Some(generics), Some(substs)) = (generics, substs) { - let args = cx.generic_args_to_print(generics, substs); - cx.path_generic_args(Ok, args) - } else { - Ok(cx) - }, + (cx, true) => return Ok(cx), (cx, false) => self = cx, } } @@ -942,7 +933,7 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; let span = self.tcx.def_span(def_id); return self.path_append( - |cx| cx.print_def_path(parent_def_id, None), + |cx| cx.print_def_path(parent_def_id, &[]), &format!("", span), ); } @@ -1073,7 +1064,7 @@ impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> fn print_value_path( mut self, def_id: DefId, - substs: Option>, + substs: &'tcx [Kind<'tcx>], ) -> Result { let was_in_value = std::mem::replace(&mut self.in_value, true); self = self.print_def_path(def_id, substs)?; @@ -1476,7 +1467,7 @@ define_print_and_forward_display! { ty::ExistentialPredicate::Trait(x) => p!(print(x)), ty::ExistentialPredicate::Projection(x) => p!(print(x)), ty::ExistentialPredicate::AutoTrait(def_id) => { - p!(print_def_path(def_id, None)); + p!(print_def_path(def_id, &[])); } } } @@ -1509,7 +1500,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - p!(print_def_path(self.def_id, Some(self.substs))); + p!(print_def_path(self.def_id, self.substs)); } ConstValue<'tcx> { @@ -1553,7 +1544,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - p!(print_def_path(self.item_def_id, Some(self.substs))); + p!(print_def_path(self.item_def_id, self.substs)); } ty::ClosureKind { @@ -1574,17 +1565,17 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `"), - print_def_path(trait_def_id, None), + print_def_path(trait_def_id, &[]), write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `"), - print_value_path(closure_def_id, None), + print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `"), - print_value_path(def_id, Some(substs)), + print_value_path(def_id, substs), write("` can be evaluated")) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 4cbb315cefadb..6aabdf1e5661f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -36,7 +36,7 @@ impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { FmtPrinter::new(tcx, f, Namespace::TypeNS) - .print_def_path(self.def_id, None)?; + .print_def_path(self.def_id, &[])?; Ok(()) }) } @@ -46,7 +46,7 @@ impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { FmtPrinter::new(tcx, f, Namespace::TypeNS) - .print_def_path(self.did, None)?; + .print_def_path(self.did, &[])?; Ok(()) }) } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index d1fcc88e59900..262ba8a1c747f 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -227,7 +227,7 @@ fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty:: tcx, path: SymbolPath::new(), keep_within_component: false, - }.print_def_path(def_id, None).unwrap().path.into_interned() + }.print_def_path(def_id, &[]).unwrap().path.into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -438,7 +438,7 @@ impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | ty::Closure(def_id, ty::ClosureSubsts { substs }) | ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { - self.print_def_path(def_id, Some(substs)) + self.print_def_path(def_id, substs) } _ => self.pretty_print_type(ty), } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0f0811b562ea3..c4e371d5afedb 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -12,7 +12,7 @@ use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Pla use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; -use rustc::ty::{self, DefIdTree, TyCtxt}; +use rustc::ty::{self, TyCtxt}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, Level}; use rustc_data_structures::bit_set::BitSet; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 53087eb1b1aba..da73eb0cda5db 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4322,7 +4322,7 @@ pub fn get_path_for_type( } let names = AbsolutePathPrinter { tcx: tcx.global_tcx() } - .print_def_path(def_id, None) + .print_def_path(def_id, &[]) .unwrap(); hir::Path { diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 22c871dd3c04e..99fa3b9679482 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -462,11 +462,11 @@ note: required by `check` LL | fn check(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}: Impossible` is not satisfied +error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}: Impossible` is not satisfied --> $DIR/namespace-mix.rs:128:5 | LL | check(xm9::TV); - | ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::c::E::TV}` + | ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}` | note: required by `check` --> $DIR/namespace-mix.rs:21:1 From a54a41ce47c149fd6587182a4ab87a146844f939 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 3 Feb 2019 12:59:37 +0200 Subject: [PATCH 146/157] rustc: provide DisambiguatedDefPathData in ty::print. --- src/librustc/hir/map/definitions.rs | 6 +- src/librustc/infer/error_reporting/mod.rs | 6 +- src/librustc/ty/print/mod.rs | 12 ++- src/librustc/ty/print/pretty.rs | 88 +++++++++++++------ src/librustc_codegen_utils/symbol_names.rs | 26 +++++- src/librustdoc/clean/mod.rs | 6 +- src/test/mir-opt/retag.rs | 2 +- src/test/ui/consts/const-size_of-cycle.stderr | 8 +- src/test/ui/deprecation/deprecation-lint.rs | 2 +- .../ui/deprecation/deprecation-lint.stderr | 2 +- src/test/ui/impl-trait/auto-trait-leak.stderr | 12 +-- src/test/ui/issues/issue-17252.stderr | 2 +- src/test/ui/issues/issue-23302-1.stderr | 6 +- src/test/ui/issues/issue-23302-2.stderr | 6 +- src/test/ui/issues/issue-36163.stderr | 6 +- src/test/ui/issues/issue-44415.stderr | 8 +- 16 files changed, 127 insertions(+), 71 deletions(-) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index f454d691d4188..dca4ce4aef817 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -679,13 +679,13 @@ impl DefPathData { return name } // note that this does not show up in user printouts - CrateRoot => "{{root}}", + CrateRoot => "{{crate}}", Impl => "{{impl}}", - Misc => "{{?}}", + Misc => "{{misc}}", ClosureExpr => "{{closure}}", StructCtor => "{{constructor}}", AnonConst => "{{constant}}", - ImplTrait => "{{impl-Trait}}", + ImplTrait => "{{opaque}}", }; Symbol::intern(s).as_interned_str() diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5026074f5e820..2810b5a8e6ada 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -445,6 +445,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sp: Span, ) { use hir::def_id::CrateNum; + use hir::map::DisambiguatedDefPathData; use ty::print::Printer; use ty::subst::Kind; @@ -504,6 +505,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn path_append_impl( self, _print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, _self_ty: Ty<'tcx>, _trait_ref: Option>, ) -> Result { @@ -512,10 +514,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn path_append( self, print_prefix: impl FnOnce(Self) -> Result, - text: &str, + disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let mut path = print_prefix(self)?; - path.push(text.to_string()); + path.push(disambiguated_data.data.as_interned_str().to_string()); Ok(path) } fn path_generic_args( diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index c3f4a26a57ee8..99b83deab8bab 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,4 +1,4 @@ -use crate::hir::map::DefPathData; +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::subst::{Kind, Subst}; @@ -71,13 +71,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { fn path_append_impl( self, print_prefix: impl FnOnce(Self) -> Result, + disambiguated_data: &DisambiguatedDefPathData, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result; fn path_append( self, print_prefix: impl FnOnce(Self) -> Result, - text: &str, + disambiguated_data: &DisambiguatedDefPathData, ) -> Result; fn path_generic_args( self, @@ -156,7 +157,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { } else { cx.print_def_path(parent_def_id, parent_substs) }, - &key.disambiguated_data.data.as_interned_str().as_str(), + &key.disambiguated_data, ) } } @@ -200,12 +201,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", impl_def_id, self_ty, impl_trait_ref); + let key = self.tcx().def_key(impl_def_id); + let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; + // Decide whether to print the parent path for the impl. // Logically, since impls are global, it's never needed, but // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let parent_def_id = self.tcx().parent(impl_def_id).unwrap(); let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id), @@ -221,6 +224,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { // the module more clearly. self.path_append_impl( |cx| cx.print_def_path(parent_def_id, &[]), + &key.disambiguated_data, self_ty, impl_trait_ref, ) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 54ca63b457af7..258903e1f1044 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1,6 +1,6 @@ use crate::hir; use crate::hir::def::Namespace; -use crate::hir::map::DefPathData; +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use crate::middle::region; @@ -313,13 +313,13 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: visible_parent, actual_parent, ); - let data = cur_def_key.disambiguated_data.data; + let mut data = cur_def_key.disambiguated_data.data; debug!( "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", data, visible_parent, actual_parent, ); - let symbol = match data { + match data { // In order to output a path that could actually be imported (valid and visible), // we need to handle re-exports correctly. // @@ -351,27 +351,30 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: // the children of the visible parent (as was done when computing // `visible_parent_map`), looking for the specific child we currently have and then // have access to the re-exported name. - DefPathData::Module(actual_name) | - DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - self.tcx().item_children(visible_parent) + DefPathData::Module(ref mut name) | + DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { + let reexport = self.tcx().item_children(visible_parent) .iter() .find(|child| child.def.def_id() == def_id) - .map(|child| child.ident.as_str()) - .unwrap_or_else(|| actual_name.as_str()) + .map(|child| child.ident.as_interned_str()); + if let Some(reexport) = reexport { + *name = reexport; + } } - _ => { - data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { - // Re-exported `extern crate` (#43189). - if let DefPathData::CrateRoot = data { - self.tcx().original_crate_name(def_id.krate).as_str() - } else { - Symbol::intern("").as_str() - } - }) - }, - }; - debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok((self.path_append(Ok, &symbol)?, true)) + // Re-exported `extern crate` (#43189). + DefPathData::CrateRoot => { + data = DefPathData::Module( + self.tcx().original_crate_name(def_id.krate).as_interned_str(), + ); + } + _ => {} + } + debug!("try_print_visible_def_path: data={:?}", data); + + Ok((self.path_append(Ok, &DisambiguatedDefPathData { + data, + disambiguator: 0, + })?, true)) } fn pretty_path_qualified( @@ -932,10 +935,18 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { // only occur very early in the compiler pipeline. let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; let span = self.tcx.def_span(def_id); - return self.path_append( - |cx| cx.print_def_path(parent_def_id, &[]), - &format!("", span), - ); + + self = self.print_def_path(parent_def_id, &[])?; + + // HACK(eddyb) copy of `path_append` to avoid + // constructing a `DisambiguatedDefPathData`. + if !self.empty_path { + write!(self, "::")?; + } + write!(self, "", span)?; + self.empty_path = false; + + return Ok(self); } } @@ -995,6 +1006,7 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { fn path_append_impl( mut self, print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -1012,17 +1024,35 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { fn path_append( mut self, print_prefix: impl FnOnce(Self) -> Result, - text: &str, + disambiguated_data: &DisambiguatedDefPathData, ) -> Result { self = print_prefix(self)?; - // FIXME(eddyb) `text` should never be empty, but it + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::StructCtor => return Ok(self), + _ => {} + } + + // FIXME(eddyb) `name` should never be empty, but it // currently is for `extern { ... }` "foreign modules". - if !text.is_empty() { + let name = disambiguated_data.data.as_interned_str().as_str(); + if !name.is_empty() { if !self.empty_path { write!(self, "::")?; } - write!(self, "{}", text)?; + write!(self, "{}", name)?; + + // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it + // might be nicer to use something else, e.g. `{closure#3}`. + let dis = disambiguated_data.disambiguator; + let print_dis = + disambiguated_data.data.get_opt_name().is_none() || + dis != 0 && self.tcx.sess.verbose(); + if print_dis { + write!(self, "#{}", dis)?; + } + self.empty_path = false; } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 262ba8a1c747f..0fa935199f97b 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -90,7 +90,7 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; -use rustc::hir::map::definitions::DefPathData; +use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; use rustc::ich::NodeIdHashingMode; use rustc::ty::print::{PrettyPrinter, Printer, Print}; use rustc::ty::query::Providers; @@ -492,11 +492,23 @@ impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { fn path_append_impl( self, print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { self.pretty_path_append_impl( - |cx| cx.path_append(print_prefix, ""), + |mut cx| { + cx = print_prefix(cx)?; + + if cx.keep_within_component { + // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. + cx.write_str("::")?; + } else { + cx.path.finalize_pending_component(); + } + + Ok(cx) + }, self_ty, trait_ref, ) @@ -504,10 +516,16 @@ impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { fn path_append( mut self, print_prefix: impl FnOnce(Self) -> Result, - text: &str, + disambiguated_data: &DisambiguatedDefPathData, ) -> Result { self = print_prefix(self)?; + // Skip `::{{constructor}}` on tuple/unit structs. + match disambiguated_data.data { + DefPathData::StructCtor => return Ok(self), + _ => {} + } + if self.keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. self.write_str("::")?; @@ -515,7 +533,7 @@ impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { self.path.finalize_pending_component(); } - self.write_str(text)?; + self.write_str(&disambiguated_data.data.as_interned_str().as_str())?; Ok(self) } fn path_generic_args( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index da73eb0cda5db..c80fd8fcd812f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,6 +20,7 @@ use rustc::mir::interpret::GlobalId; use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::map::DisambiguatedDefPathData; use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; @@ -4288,6 +4289,7 @@ pub fn get_path_for_type( fn path_append_impl( self, print_prefix: impl FnOnce(Self) -> Result, + _disambiguated_data: &DisambiguatedDefPathData, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -4306,10 +4308,10 @@ pub fn get_path_for_type( fn path_append( self, print_prefix: impl FnOnce(Self) -> Result, - text: &str, + disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let mut path = print_prefix(self)?; - path.push(text.to_string()); + path.push(disambiguated_data.data.as_interned_str().to_string()); Ok(path) } fn path_generic_args( diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index cdf635567378e..3b333b5431c3e 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -98,7 +98,7 @@ fn main() { // } // END rustc.main.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 { +// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 { // ... // bb0: { // Retag([fn entry] _1); diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 8f8eb38e93873..3762f5e3d6ad8 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -1,22 +1,22 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}` +error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` --> $DIR/const-size_of-cycle.rs:6:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... --> $SRC_DIR/libcore/mem.rs:LL:COL | LL | intrinsics::size_of::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... -note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... --> $DIR/const-size_of-cycle.rs:6:17 | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle + = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle note: cycle used when processing `Foo` --> $DIR/const-size_of-cycle.rs:5:1 | diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs index 033d6eebbb219..26271395005a7 100644 --- a/src/test/ui/deprecation/deprecation-lint.rs +++ b/src/test/ui/deprecation/deprecation-lint.rs @@ -314,7 +314,7 @@ mod this_crate { let _ = || { #[deprecated] fn bar() { } - bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar' + bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' }; } diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index 50cbe3846bba6..ffbcb259754e7 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -298,7 +298,7 @@ error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text LL | ::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}::bar' +error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' --> $DIR/deprecation-lint.rs:317:13 | LL | bar(); diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index b936fed85f48e..4e79dfc3f7c01 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}` +error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0` --> $DIR/auto-trait-leak.rs:14:16 | LL | fn cycle1() -> impl Clone { @@ -10,7 +10,7 @@ note: ...which requires processing `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires processing `cycle2::{{impl-Trait}}`... +note: ...which requires processing `cycle2::{{opaque}}#0`... --> $DIR/auto-trait-leak.rs:23:16 | LL | fn cycle2() -> impl Clone { @@ -21,7 +21,7 @@ note: ...which requires processing `cycle2`... LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... - = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle + = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:3:1 | @@ -34,7 +34,7 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}` +error[E0391]: cycle detected when processing `cycle1::{{opaque}}#0` --> $DIR/auto-trait-leak.rs:14:16 | LL | fn cycle1() -> impl Clone { @@ -46,7 +46,7 @@ note: ...which requires processing `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... -note: ...which requires processing `cycle2::{{impl-Trait}}`... +note: ...which requires processing `cycle2::{{opaque}}#0`... --> $DIR/auto-trait-leak.rs:23:16 | LL | fn cycle2() -> impl Clone { @@ -56,7 +56,7 @@ note: ...which requires processing `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle + = note: ...which again requires processing `cycle1::{{opaque}}#0`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:3:1 | diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index c993588f55314..da3e2e763af58 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -5,7 +5,7 @@ LL | const FOO: usize = FOO; | ^^^ | = note: ...which again requires processing `FOO`, completing the cycle -note: cycle used when processing `main::{{constant}}` +note: cycle used when processing `main::{{constant}}#0` --> $DIR/issue-17252.rs:4:18 | LL | let _x: [u8; FOO]; // caused stack overflow prior to fix diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index 5fa82f8b78635..43effc0b3b974 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,11 +1,11 @@ -error[E0391]: cycle detected when processing `X::A::{{constant}}` +error[E0391]: cycle detected when processing `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires processing `X::A::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `X::A::{{constant}}` + = note: ...which again requires processing `X::A::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index 5b77baed73c3d..707d4fa7ed3f7 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,11 +1,11 @@ -error[E0391]: cycle detected when processing `Y::A::{{constant}}` +error[E0391]: cycle detected when processing `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires processing `Y::A::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `Y::A::{{constant}}` + = note: ...which again requires processing `Y::A::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, diff --git a/src/test/ui/issues/issue-36163.stderr b/src/test/ui/issues/issue-36163.stderr index 94de4c76927a5..4c3f726180dfe 100644 --- a/src/test/ui/issues/issue-36163.stderr +++ b/src/test/ui/issues/issue-36163.stderr @@ -1,4 +1,4 @@ -error[E0391]: cycle detected when processing `Foo::B::{{constant}}` +error[E0391]: cycle detected when processing `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, @@ -9,8 +9,8 @@ note: ...which requires processing `A`... | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^ - = note: ...which again requires processing `Foo::B::{{constant}}`, completing the cycle -note: cycle used when const-evaluating `Foo::B::{{constant}}` + = note: ...which again requires processing `Foo::B::{{constant}}#0`, completing the cycle +note: cycle used when const-evaluating `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr index 3f377fd27e7db..df8e804c87a3f 100644 --- a/src/test/ui/issues/issue-44415.stderr +++ b/src/test/ui/issues/issue-44415.stderr @@ -1,22 +1,22 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}` +error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0` --> $DIR/issue-44415.rs:6:17 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^ | -note: ...which requires const-evaluating `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`... --> $DIR/issue-44415.rs:6:26 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`... -note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}`... +note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`... --> $DIR/issue-44415.rs:6:17 | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^ - = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}`, completing the cycle + = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle note: cycle used when processing `Foo` --> $DIR/issue-44415.rs:5:1 | From 22d6c55cdf1772b0cfbed371dca16b3f3769117f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 4 Feb 2019 00:48:16 +0200 Subject: [PATCH 147/157] rustc: print ExistentialProjection with spaces around `=`, e.g. `dyn Foo`. --- src/librustc/ty/print/pretty.rs | 2 +- src/test/ui/associated-types/associated-types-eq-3.stderr | 2 +- .../associated-types-overridden-binding-2.stderr | 2 +- src/test/ui/confuse-field-and-method/issue-2392.stderr | 2 +- src/test/ui/issues/issue-20605.stderr | 4 ++-- src/test/ui/issues/issue-22312.stderr | 2 +- src/test/ui/issues/issue-55796.stderr | 8 ++++---- src/test/ui/retslot-cast.stderr | 6 +++--- .../typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr | 2 +- .../unboxed-closures/unboxed-closure-sugar-default.stderr | 4 ++-- .../unboxed-closures/unboxed-closure-sugar-equiv.stderr | 4 ++-- .../ui/underscore-lifetime/dyn-trait-underscore.stderr | 4 ++-- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 258903e1f1044..fa57e0b96745a 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1489,7 +1489,7 @@ define_print_and_forward_display! { ty::ExistentialProjection<'tcx> { let name = cx.tcx().associated_item(self.item_def_id).ident; - p!(write("{}=", name), print(self.ty)) + p!(write("{} = ", name), print(self.ty)) } ty::ExistentialPredicate<'tcx> { diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index c1a8e2002be61..31d2c5f318e50 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -29,7 +29,7 @@ LL | baz(&a); | = note: expected type `usize` found type `Bar` - = note: required for the cast to the object type `dyn Foo` + = note: required for the cast to the object type `dyn Foo` error: aborting due to 3 previous errors diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr index 8c0e5570d198d..ad0b6515490b9 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -6,7 +6,7 @@ LL | let _: &I32Iterator = &vec![42].into_iter(); | = note: expected type `u32` found type `i32` - = note: required for the cast to the object type `dyn I32Iterator` + = note: required for the cast to the object type `dyn I32Iterator` error: aborting due to previous error diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 7cd1941d80e83..456a4c18e2b30 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -75,7 +75,7 @@ LL | w.wrap.not_closure(); | = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`? -error[E0599]: no method named `closure` found for type `Obj + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for type `Obj + 'static)>>` in the current scope --> $DIR/issue-2392.rs:62:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr index f779fe51bf2d1..89df58dd2dc1b 100644 --- a/src/test/ui/issues/issue-20605.stderr +++ b/src/test/ui/issues/issue-20605.stderr @@ -1,10 +1,10 @@ -error[E0277]: the size for values of type `dyn std::iter::Iterator` cannot be known at compilation time +error[E0277]: the size for values of type `dyn std::iter::Iterator` cannot be known at compilation time --> $DIR/issue-20605.rs:2:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator` + = help: the trait `std::marker::Sized` is not implemented for `dyn std::iter::Iterator` = note: to learn more, visit = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-22312.stderr b/src/test/ui/issues/issue-22312.stderr index d8987a37f7e46..6a012b214c504 100644 --- a/src/test/ui/issues/issue-22312.stderr +++ b/src/test/ui/issues/issue-22312.stderr @@ -1,4 +1,4 @@ -error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index>::Output>` +error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index>::Output>` --> $DIR/issue-22312.rs:11:24 | LL | let indexer = &(*self as &Index>::Output>); diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index c05f8b85d0e98..7cf597d3a98f8 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -16,8 +16,8 @@ LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/issue-55796.rs:21:9 @@ -37,8 +37,8 @@ LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> - found std::boxed::Box>::Node>> + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> error: aborting due to 2 previous errors diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr index 3c58285bdb352..a1169910ae7e2 100644 --- a/src/test/ui/retslot-cast.stderr +++ b/src/test/ui/retslot-cast.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/retslot-cast.rs:13:5 | LL | inner(x) - | ^^^^^^^^ expected trait `std::iter::Iterator`, found trait `std::iter::Iterator + std::marker::Send` + | ^^^^^^^^ expected trait `std::iter::Iterator`, found trait `std::iter::Iterator + std::marker::Send` | - = note: expected type `std::option::Option<&dyn std::iter::Iterator>` - found type `std::option::Option<&dyn std::iter::Iterator + std::marker::Send>` + = note: expected type `std::option::Option<&dyn std::iter::Iterator>` + found type `std::option::Option<&dyn std::iter::Iterator + std::marker::Send>` error: aborting due to previous error diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr index f1118709962a4..d41086186f8d7 100644 --- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -7,7 +7,7 @@ LL | *x | ^^ expected (), found trait std::iter::Iterator | = note: expected type `()` - found type `(dyn std::iter::Iterator + 'static)` + found type `(dyn std::iter::Iterator + 'static)` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr index 508c2f780b9fb..ce90f5b9d2486 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output=()>: Eq>` is not satisfied +error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output = ()>: Eq>` is not satisfied --> $DIR/unboxed-closure-sugar-default.rs:21:5 | LL | eq::< Foo<(isize,),isize,Output=()>, Foo(isize) >(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq>` is not implemented for `dyn Foo<(isize,), isize, Output=()>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq>` is not implemented for `dyn Foo<(isize,), isize, Output = ()>` | note: required by `eq` --> $DIR/unboxed-closure-sugar-default.rs:14:1 diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr index 071ba2792b0ac..857a32ca69e73 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr @@ -1,9 +1,9 @@ -error[E0277]: the trait bound `dyn Foo<(char,), Output=()>: Eq>` is not satisfied +error[E0277]: the trait bound `dyn Foo<(char,), Output = ()>: Eq>` is not satisfied --> $DIR/unboxed-closure-sugar-equiv.rs:43:5 | LL | / eq::< Foo<(),Output=()>, LL | | Foo(char) >(); - | |___________________________________________________________________^ the trait `Eq>` is not implemented for `dyn Foo<(char,), Output=()>` + | |___________________________________________________________________^ the trait `Eq>` is not implemented for `dyn Foo<(char,), Output = ()>` | note: required by `eq` --> $DIR/unboxed-closure-sugar-equiv.rs:16:1 diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 69a9fd7a60c93..d0475bf08c38d 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -19,8 +19,8 @@ LL | Box::new(items.iter()) | ^^^^^ = note: but, the lifetime must be valid for the static lifetime... = note: ...so that the expression is assignable: - expected std::boxed::Box<(dyn std::iter::Iterator + 'static)> - found std::boxed::Box> + expected std::boxed::Box<(dyn std::iter::Iterator + 'static)> + found std::boxed::Box> error: aborting due to previous error From 4653ae1e3e9ce3613844987b43431b35302fb34a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 7 Feb 2019 15:02:14 +0100 Subject: [PATCH 148/157] we can now print on entering/leaving the topmost frame, and make sure it stays that way --- src/librustc_mir/const_eval.rs | 17 +++++++++-------- src/librustc_mir/interpret/eval_context.rs | 12 ++++-------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index e6005142b85ef..43f019019f7c3 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -602,14 +602,15 @@ pub fn const_eval_raw_provider<'a, 'tcx>( other => return other, } } - // the first trace is for replicating an ice - // There's no tracking issue, but the next two lines concatenated link to the discussion on - // zulip. It's not really possible to test this, because it doesn't show up in diagnostics - // or MIR. - // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ - // subject/anon_const_instance_printing/near/135980032 - trace!("const eval: {}", key.value.instance); - trace!("const eval: {:?}", key); + if cfg!(debug_assertions) { + // Make sure we format the instance even if we do not print it. + // This serves as a regression test against an ICE on printing. + // The next two lines concatenated contain some discussion: + // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ + // subject/anon_const_instance_printing/near/135980032 + let instance = key.value.instance.to_string(); + trace!("const eval: {:?} ({})", key, instance); + } let cid = key.value; let def_id = cid.instance.def.def_id(); diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d92ab0c517956..e81d0a56b2b05 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -450,7 +450,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc return_place: Option>, return_to_block: StackPopCleanup, ) -> EvalResult<'tcx> { - if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc... + if self.stack.len() > 0 { info!("PAUSING({}) {}", self.cur_frame(), self.frame().instance); } ::log_settings::settings().indentation += 1; @@ -525,9 +525,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc self.frame_mut().locals = locals; } - if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE - info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); - } + info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { err!(StackFrameLimitReached) @@ -537,9 +535,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc } pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> { - if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE - info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance); - } + info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance); ::log_settings::settings().indentation -= 1; let frame = self.stack.pop().expect( "tried to pop a stack frame, but there were none", @@ -591,7 +587,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc StackPopCleanup::None { .. } => {} } - if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc... + if self.stack.len() > 0 { info!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance); } From 0ee059d5a08662b22250e28dbd5d5a9502303afb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 14 Mar 2019 19:47:24 +0200 Subject: [PATCH 149/157] Fix rebase fallout and address some review comments. --- src/librustc/ty/print/mod.rs | 8 ++++++++ src/librustc/ty/structural_impls.rs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 99b83deab8bab..ef30a4032d8fa 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -16,6 +16,14 @@ pub trait Print<'gcx, 'tcx, P> { fn print(&self, cx: P) -> Result; } +/// Interface for outputting user-facing "type-system entities" +/// (paths, types, lifetimes, constants, etc.) as a side-effect +/// (e.g. formatting, like `PrettyPrinter` implementors do) or by +/// constructing some alternative representation (e.g. an AST), +/// which the associated types allow passing through the methods. +/// +/// For pretty-printing/formatting in particular, see `PrettyPrinter`. +// FIXME(eddyb) find a better name, this is more general than "printing". pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { type Error; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 6aabdf1e5661f..ecfb034e4f2fe 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -225,7 +225,7 @@ impl fmt::Debug for ty::FloatVarValue { impl fmt::Debug for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // HACK(eddyb) this is used across the compiler to print + // FIXME(#59188) this is used across the compiler to print // a `TraitRef` qualified (with the Self type explicit), // instead of having a different way to make that choice. write!(f, "<{} as {}>", self.self_ty(), self) From dbf19c3975a014861535b775b2fb7cd71e6c5042 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 15 Mar 2019 13:24:34 +0200 Subject: [PATCH 150/157] rustbuild: remove obsolete fulldeps behavior from src/test/pretty tests, and enable them by default. --- src/bootstrap/mk/Makefile.in | 1 - src/bootstrap/test.rs | 12 +++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 1c27cf3909b1a..07be27c2f5a02 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -48,7 +48,6 @@ check: $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) check-aux: $(Q)$(BOOTSTRAP) test \ - src/test/pretty \ src/test/run-pass/pretty \ src/test/run-fail/pretty \ src/test/run-pass-valgrind/pretty \ diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b7323b2eadc3d..81e09bc878a10 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -897,12 +897,10 @@ host_test!(Rustdoc { suite: "rustdoc" }); -test!(Pretty { +host_test!(Pretty { path: "src/test/pretty", mode: "pretty", - suite: "pretty", - default: false, - host: true + suite: "pretty" }); test!(RunPassPretty { path: "src/test/run-pass/pretty", @@ -993,11 +991,7 @@ impl Step for Compiletest { }); } - if suite.ends_with("fulldeps") || - // FIXME: Does pretty need librustc compiled? Note that there are - // fulldeps test suites with mode = pretty as well. - mode == "pretty" - { + if suite.ends_with("fulldeps") { builder.ensure(compile::Rustc { compiler, target }); } From 12e3e8412cd8eb1ec93034d52e4287dbae2027de Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Fri, 15 Mar 2019 21:48:05 +0900 Subject: [PATCH 151/157] reduced a code repetition related to bit operation. --- src/librustc_mir/hair/pattern/_match.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 586a3fdb907ee..76e04d349f15b 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const}; use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size}; use rustc::mir::Field; -use rustc::mir::interpret::{ConstValue, Scalar}; +use rustc::mir::interpret::{ConstValue, Scalar, truncate}; use rustc::util::common::ErrorReported; use syntax::attr::{SignedInt, UnsignedInt}; @@ -685,9 +685,8 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. - let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128; - let max = !0u128 >> (128 - bits); + let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); + let max = truncate(u128::max_value(), size); vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)] } _ => { From 5303c1b90b12c0edb3fbadf96f15edf93fb69155 Mon Sep 17 00:00:00 2001 From: Brian Campbell Date: Fri, 15 Mar 2019 01:51:26 -0400 Subject: [PATCH 152/157] Remove restriction on isize/usize in repr(simd) As discussed in #55078, there's no known reason for this restriction. It's unlikely that repr(simd) will be stabilized in its current form, but might as well remove some restrictions on it. This removes the branch in `is_machine` which returns false for these types. `is_machine` is only used for the repr(simd) type validation check. --- src/librustc/ty/sty.rs | 1 - src/test/run-pass/simd/simd-size-align.rs | 32 +++++++++++++++++++++++ src/test/ui/simd-type.rs | 3 --- src/test/ui/simd-type.stderr | 10 ++----- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 39728cc8cd5cb..2db4caaff92bc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1910,7 +1910,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_machine(&self) -> bool { match self.sty { - Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false, Int(..) | Uint(..) | Float(..) => true, _ => false, } diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs index 0a537071a3c63..556013788c335 100644 --- a/src/test/run-pass/simd/simd-size-align.rs +++ b/src/test/run-pass/simd/simd-size-align.rs @@ -37,6 +37,22 @@ fn main() { check::(); check::(); check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); } #[repr(simd)] struct u8x2(u8, u8); @@ -62,3 +78,19 @@ fn main() { #[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + +#[repr(simd)] struct usizex2(usize, usize); +#[repr(simd)] struct usizex3(usize, usize, usize); +#[repr(simd)] struct usizex4(usize, usize, usize, usize); +#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize); + +#[repr(simd)] struct isizex2(isize, isize); +#[repr(simd)] struct isizex3(isize, isize, isize); +#[repr(simd)] struct isizex4(isize, isize, isize, isize); +#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize); diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs index d1e2efa6a3331..9e4b7e7656055 100644 --- a/src/test/ui/simd-type.rs +++ b/src/test/ui/simd-type.rs @@ -7,7 +7,4 @@ struct empty; //~ ERROR SIMD vector cannot be empty #[repr(simd)] struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous -#[repr(simd)] -struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type - fn main() {} diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr index 027afcb981a0d..48b9916e89d98 100644 --- a/src/test/ui/simd-type.stderr +++ b/src/test/ui/simd-type.stderr @@ -10,13 +10,7 @@ error[E0076]: SIMD vector should be homogeneous LL | struct i64f64(i64, f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type -error[E0077]: SIMD vector element type should be machine type - --> $DIR/simd-type.rs:11:1 - | -LL | struct int4(isize, isize, isize, isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0075, E0076, E0077. +Some errors occurred: E0075, E0076. For more information about an error, try `rustc --explain E0075`. From 9c7bf76c087d4d579d1af5dc9a3f4fa9d81a3a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 15 Mar 2019 15:43:56 +0100 Subject: [PATCH 153/157] Add x86_64 musl host to the manifest --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index d44a51a9635e9..f0b8ab13dc567 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -32,6 +32,7 @@ static HOSTS: &'static [&'static str] = &[ "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", ]; From 50af62dae912d2b0ea24aef649bce7be8b7040a8 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Sat, 16 Mar 2019 01:14:46 +0900 Subject: [PATCH 154/157] removed some unnecessary comments. --- src/librustc_mir/build/matches/simplify.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index d60a0941b5979..77978d7d38ff7 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); let max = truncate(u128::max_value(), size); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); let max = truncate(u128::max_value(), size); (Some((0, max, size)), 0) From a8fa1a153d332d31d7d95ce303bf2b347b7a03c5 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Sat, 16 Mar 2019 01:58:48 +0900 Subject: [PATCH 155/157] a simple refactoring and removing comment. --- src/librustc_mir/hair/pattern/_match.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 76e04d349f15b..44bcb9de0e157 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -678,10 +678,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ] } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; let min = 1u128 << (bits - 1); - let max = (1u128 << (bits - 1)) - 1; + let max = min - 1; vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { From 9a61580d40df576d6774028cbba6a49b3c9dc0fe Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 15 Mar 2019 16:42:10 -0400 Subject: [PATCH 156/157] Option and Result: Add references to documentation of as_ref and as_mut --- src/libcore/option.rs | 4 ++-- src/libcore/result.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 46dfe28da622c..75fa24aa4dc1d 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -210,7 +210,7 @@ impl Option { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Option` to `Option<&T>`. + /// Converts from `&Option` to `Option<&T>`. /// /// # Examples /// @@ -239,7 +239,7 @@ impl Option { } } - /// Converts from `Option` to `Option<&mut T>`. + /// Converts from `&mut Option` to `Option<&mut T>`. /// /// # Examples /// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 2bd6b536301e8..967f7e3e2fe72 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -369,7 +369,7 @@ impl Result { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Result` to `Result<&T, &E>`. + /// Converts from `&Result` to `Result<&T, &E>`. /// /// Produces a new `Result`, containing a reference /// into the original, leaving the original in place. @@ -394,7 +394,7 @@ impl Result { } } - /// Converts from `Result` to `Result<&mut T, &mut E>`. + /// Converts from `&mut Result` to `Result<&mut T, &mut E>`. /// /// # Examples /// From 08f264d5762fc8cf817288084c03ce0d53ecb85b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 16 Mar 2019 14:11:23 +0300 Subject: [PATCH 157/157] Stabilize Option::copied closes https://github.com/rust-lang/rust/issues/57126 --- src/libcore/option.rs | 8 ++------ src/libcore/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 46dfe28da622c..f7f7e96fff32e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -881,15 +881,13 @@ impl Option<&T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let x = 12; /// let opt_x = Some(&x); /// assert_eq!(opt_x, Some(&12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&t| t) } @@ -902,15 +900,13 @@ impl Option<&mut T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let mut x = 12; /// let opt_x = Some(&mut x); /// assert_eq!(opt_x, Some(&mut 12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&mut t| t) } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index d002137638977..a50310e195f0d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -1,6 +1,5 @@ #![feature(box_syntax)] #![feature(cell_update)] -#![feature(copied)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)]

(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool { if cx.is_verbose { return true; } @@ -1044,28 +1037,28 @@ impl ty::RegionVid { } define_print! { - () ty::InferTy, (self, f, cx) { + () ty::InferTy, (self, cx) { display { if cx.is_verbose { - return self.print_debug(f, cx); + return self.print_debug(cx); } match *self { - ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) => write!(f, "{}", "{integer}"), - ty::FloatVar(_) => write!(f, "{}", "{float}"), - ty::FreshTy(v) => write!(f, "FreshTy({})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) + ty::TyVar(_) => print!(cx, write("_")), + ty::IntVar(_) => print!(cx, write("{}", "{integer}")), + ty::FloatVar(_) => print!(cx, write("{}", "{float}")), + ty::FreshTy(v) => print!(cx, write("FreshTy({})", v)), + ty::FreshIntTy(v) => print!(cx, write("FreshIntTy({})", v)), + ty::FreshFloatTy(v) => print!(cx, write("FreshFloatTy({})", v)) } } debug { match *self { - ty::TyVar(ref v) => write!(f, "{:?}", v), - ty::IntVar(ref v) => write!(f, "{:?}", v), - ty::FloatVar(ref v) => write!(f, "{:?}", v), - ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v) + ty::TyVar(ref v) => print!(cx, write("{:?}", v)), + ty::IntVar(ref v) => print!(cx, write("{:?}", v)), + ty::FloatVar(ref v) => print!(cx, write("{:?}", v)), + ty::FreshTy(v) => print!(cx, write("FreshTy({:?})", v)), + ty::FreshIntTy(v) => print!(cx, write("FreshIntTy({:?})", v)), + ty::FreshFloatTy(v) => print!(cx, write("FreshFloatTy({:?})", v)) } } } @@ -1093,7 +1086,7 @@ impl fmt::Debug for ty::FloatVarValue { for<'a> >::Lifted: fmt::Display + TypeFoldable<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|cx| cx.in_binder(f, cx.tcx.lift(self) + PrintCx::with(|cx| cx.in_binder(cx.tcx.lift(self) .expect("could not lift for printing"))) } }*/ @@ -1109,136 +1102,131 @@ define_print_multi! { ('tcx) ty::Binder, ty::Region<'tcx>>>, ('tcx) ty::Binder, ty::Region<'tcx>>> ] - (self, f, cx) { + (self, cx) { display { - cx.in_binder(f, self) + cx.in_binder(self) } } } define_print! { - ('tcx) ty::TraitRef<'tcx>, (self, f, cx) { + ('tcx) ty::TraitRef<'tcx>, (self, cx) { display { - cx.parameterized(f, self.def_id, self.substs, iter::empty()) + cx.parameterized(self.def_id, self.substs, iter::empty()) } debug { - // when printing out the debug representation, we don't need - // to enumerate the `for<...>` etc because the debruijn index - // tells you everything you need to know. - print!(f, cx, - write("<"), - print(self.self_ty()), - write(" as "))?; - cx.parameterized(f, self.def_id, self.substs, iter::empty())?; - write!(f, ">") + print!(cx, write("<"), print(self.self_ty()), write(" as "))?; + cx.parameterized(self.def_id, self.substs, iter::empty())?; + print!(cx, write(">")) } } } define_print! { - ('tcx) ty::Ty<'tcx>, (self, f, cx) { + ('tcx) ty::Ty<'tcx>, (self, cx) { display { match self.sty { - Bool => write!(f, "bool"), - Char => write!(f, "char"), - Int(t) => write!(f, "{}", t.ty_to_string()), - Uint(t) => write!(f, "{}", t.ty_to_string()), - Float(t) => write!(f, "{}", t.ty_to_string()), + Bool => print!(cx, write("bool")), + Char => print!(cx, write("char")), + Int(t) => print!(cx, write("{}", t.ty_to_string())), + Uint(t) => print!(cx, write("{}", t.ty_to_string())), + Float(t) => print!(cx, write("{}", t.ty_to_string())), RawPtr(ref tm) => { - write!(f, "*{} ", match tm.mutbl { + print!(cx, write("*{} ", match tm.mutbl { hir::MutMutable => "mut", hir::MutImmutable => "const", - })?; - tm.ty.print(f, cx) + }))?; + tm.ty.print(cx) } Ref(r, ty, mutbl) => { - write!(f, "&")?; + print!(cx, write("&"))?; if r.display_outputs_anything(cx) { - print!(f, cx, print_display(r), write(" "))?; + print!(cx, print_display(r), write(" "))?; } - ty::TypeAndMut { ty, mutbl }.print(f, cx) + ty::TypeAndMut { ty, mutbl }.print(cx) } - Never => write!(f, "!"), + Never => print!(cx, write("!")), Tuple(ref tys) => { - write!(f, "(")?; + print!(cx, write("("))?; let mut tys = tys.iter(); if let Some(&ty) = tys.next() { - print!(f, cx, print(ty), write(","))?; + print!(cx, print(ty), write(","))?; if let Some(&ty) = tys.next() { - print!(f, cx, write(" "), print(ty))?; + print!(cx, write(" "), print(ty))?; for &ty in tys { - print!(f, cx, write(", "), print(ty))?; + print!(cx, write(", "), print(ty))?; } } } - write!(f, ")") + print!(cx, write(")")) } FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); - print!(f, cx, print(sig), write(" {{"))?; - cx.parameterized(f, def_id, substs, iter::empty())?; - write!(f, "}}") + print!(cx, print(sig), write(" {{"))?; + cx.parameterized(def_id, substs, iter::empty())?; + print!(cx, write("}}")) } FnPtr(ref bare_fn) => { - bare_fn.print(f, cx) + bare_fn.print(cx) } - Infer(infer_ty) => write!(f, "{}", infer_ty), - Error => write!(f, "[type error]"), - Param(ref param_ty) => write!(f, "{}", param_ty), + Infer(infer_ty) => print!(cx, write("{}", infer_ty)), + Error => print!(cx, write("[type error]")), + Param(ref param_ty) => print!(cx, write("{}", param_ty)), Bound(debruijn, bound_ty) => { match bound_ty.kind { ty::BoundTyKind::Anon => { if debruijn == ty::INNERMOST { - write!(f, "^{}", bound_ty.var.index()) + print!(cx, write("^{}", bound_ty.var.index())) } else { - write!(f, "^{}_{}", debruijn.index(), bound_ty.var.index()) + print!(cx, write("^{}_{}", debruijn.index(), bound_ty.var.index())) } } - ty::BoundTyKind::Param(p) => write!(f, "{}", p), + ty::BoundTyKind::Param(p) => print!(cx, write("{}", p)), } } - Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()), + Adt(def, substs) => cx.parameterized(def.did, substs, iter::empty()), Dynamic(data, r) => { let print_r = r.display_outputs_anything(cx); if print_r { - write!(f, "(")?; + print!(cx, write("("))?; } - write!(f, "dyn ")?; - data.print(f, cx)?; + print!(cx, write("dyn "))?; + data.print(cx)?; if print_r { - print!(f, cx, write(" + "), print_display(r), write(")"))?; + print!(cx, write(" + "), print_display(r), write(")"))?; } Ok(()) } Foreign(def_id) => { - cx.parameterized(f, def_id, subst::InternalSubsts::empty(), iter::empty()) + cx.parameterized(def_id, subst::InternalSubsts::empty(), iter::empty()) } - Projection(ref data) => data.print(f, cx), + Projection(ref data) => data.print(cx), UnnormalizedProjection(ref data) => { - write!(f, "Unnormalized(")?; - data.print(f, cx)?; - write!(f, ")") + print!(cx, write("Unnormalized("))?; + data.print(cx)?; + print!(cx, write(")")) } Placeholder(placeholder) => { - write!(f, "Placeholder({:?})", placeholder) + print!(cx, write("Placeholder({:?})", placeholder)) } Opaque(def_id, substs) => { if cx.is_verbose { - return write!(f, "Opaque({:?}, {:?})", def_id, substs); + return print!(cx, write("Opaque({:?}, {:?})", def_id, substs)); } let def_key = cx.tcx.def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - write!(f, "{}", name)?; + print!(cx, write("{}", name))?; let mut substs = substs.iter(); + // FIXME(eddyb) print this with `parameterized`. if let Some(first) = substs.next() { - write!(f, "::<")?; - write!(f, "{}", first)?; + print!(cx, write("::<"))?; + print!(cx, write("{}", first))?; for subst in substs { - write!(f, ", {}", subst)?; + print!(cx, write(", {}", subst))?; } - write!(f, ">")?; + print!(cx, write(">"))?; } return Ok(()); } @@ -1248,7 +1236,7 @@ define_print! { let mut first = true; let mut is_sized = false; - write!(f, "impl")?; + print!(cx, write("impl"))?; for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. @@ -1257,35 +1245,36 @@ define_print! { continue; } - print!(f, cx, + print!(cx, write("{}", if first { " " } else { "+" }), print(trait_ref))?; first = false; } } if !is_sized { - write!(f, "{}?Sized", if first { " " } else { "+" })?; - } else if first { - write!(f, " Sized")?; + print!(cx, write("{}?Sized", if first { " " } else { "+" }))?; + } else if first { + print!(cx, write(" Sized"))?; } Ok(()) } - Str => write!(f, "str"), + Str => print!(cx, write("str")), Generator(did, substs, movability) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); let witness = substs.witness(did, cx.tcx); if movability == hir::GeneratorMovability::Movable { - write!(f, "[generator")?; + print!(cx, write("[generator"))?; } else { - write!(f, "[static generator")?; + print!(cx, write("[static generator"))?; } + // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { - write!(f, "@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))?; + print!(cx, write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, + print!(cx, write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), @@ -1297,35 +1286,36 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - write!(f, "@{:?}", did)?; + print!(cx, write("@{:?}", did))?; let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - print!(f, cx, + print!(cx, write("{}{}:", sep, index), print(upvar_ty))?; sep = ", "; } } - print!(f, cx, write(" "), print(witness), write("]")) + print!(cx, write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { - cx.in_binder(f, &types) + cx.in_binder(&types) } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); - write!(f, "[closure")?; + print!(cx, write("[closure"))?; + // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { if cx.tcx.sess.opts.debugging_opts.span_free_formats { - write!(f, "@{:?}", hir_id)?; + print!(cx, write("@{:?}", hir_id))?; } else { - write!(f, "@{:?}", cx.tcx.hir().span_by_hir_id(hir_id))?; + print!(cx, write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)))?; } let mut sep = " "; cx.tcx.with_freevars(hir_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, + print!(cx, write("{}{}:", sep, cx.tcx.hir().name(freevar.var_id())), @@ -1337,10 +1327,10 @@ define_print! { } else { // cross-crate closure types should only be // visible in codegen bug reports, I imagine. - write!(f, "@{:?}", did)?; + print!(cx, write("@{:?}", did))?; let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - print!(f, cx, + print!(cx, write("{}{}:", sep, index), print(upvar_ty))?; sep = ", "; @@ -1348,93 +1338,93 @@ define_print! { } if cx.is_verbose { - write!( - f, + print!(cx, write( " closure_kind_ty={:?} closure_sig_ty={:?}", substs.closure_kind_ty(did, cx.tcx), - substs.closure_sig_ty(did, cx.tcx), - )?; + substs.closure_sig_ty(did, cx.tcx) + ))?; } - write!(f, "]") + print!(cx, write("]")) }, Array(ty, sz) => { - print!(f, cx, write("["), print(ty), write("; "))?; + print!(cx, write("["), print(ty), write("; "))?; match sz { ty::LazyConst::Unevaluated(_def_id, _substs) => { - write!(f, "_")?; + print!(cx, write("_"))?; } ty::LazyConst::Evaluated(c) => { match c.val { - ConstValue::Infer(..) => write!(f, "_")?, + ConstValue::Infer(..) => print!(cx, write("_"))?, ConstValue::Param(ParamConst { name, .. }) => - write!(f, "{}", name)?, - _ => write!(f, "{}", c.unwrap_usize(cx.tcx))?, + print!(cx, write("{}", name))?, + _ => print!(cx, write("{}", c.unwrap_usize(cx.tcx)))?, } } } - write!(f, "]") + print!(cx, write("]")) } Slice(ty) => { - print!(f, cx, write("["), print(ty), write("]")) + print!(cx, write("["), print(ty), write("]")) } } } debug { - self.print_display(f, cx) + self.print_display(cx) } } } define_print! { - ('tcx) ConstValue<'tcx>, (self, f, cx) { + ('tcx) ConstValue<'tcx>, (self, cx) { display { match self { - ConstValue::Infer(..) => write!(f, "_"), - ConstValue::Param(ParamConst { name, .. }) => write!(f, "{}", name), - _ => write!(f, "{:?}", self), + ConstValue::Infer(..) => print!(cx, write("_")), + ConstValue::Param(ParamConst { name, .. }) => print!(cx, write("{}", name)), + _ => print!(cx, write("{:?}", self)), } } } } define_print! { - ('tcx) ty::Const<'tcx>, (self, f, cx) { + ('tcx) ty::Const<'tcx>, (self, cx) { display { - write!(f, "{} : {}", self.val, self.ty) + print!(cx, write("{} : {}", self.val, self.ty)) } } } define_print! { - ('tcx) ty::LazyConst<'tcx>, (self, f, cx) { + ('tcx) ty::LazyConst<'tcx>, (self, cx) { display { match self { - ty::LazyConst::Unevaluated(..) => write!(f, "_ : _"), - ty::LazyConst::Evaluated(c) => write!(f, "{}", c), + // FIXME(const_generics) this should print at least the type. + ty::LazyConst::Unevaluated(..) => print!(cx, write("_ : _")), + ty::LazyConst::Evaluated(c) => print!(cx, write("{}", c)), } } } } define_print! { - () ty::ParamTy, (self, f, cx) { + () ty::ParamTy, (self, cx) { display { - write!(f, "{}", self.name) + print!(cx, write("{}", self.name)) } debug { - write!(f, "{}/#{}", self.name, self.idx) + print!(cx, write("{}/#{}", self.name, self.idx)) } } } define_print! { - () ty::ParamConst, (self, f, cx) { + () ty::ParamConst, (self, cx) { display { - write!(f, "{}", self.name) + print!(cx, write("{}", self.name)) } debug { - write!(f, "{}/#{}", self.name, self.index) + print!(cx, write("{}/#{}", self.name, self.index)) } } } @@ -1445,37 +1435,37 @@ define_print_multi! { ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>>, ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>> ] - (self, f, cx) { + (self, cx) { display { - print!(f, cx, print(self.0), write(" : "), print(self.1)) + print!(cx, print(self.0), write(" : "), print(self.1)) } } } define_print! { - ('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) { + ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) { display { - print!(f, cx, print(self.a), write(" <: "), print(self.b)) + print!(cx, print(self.a), write(" <: "), print(self.b)) } } } define_print! { - ('tcx) ty::TraitPredicate<'tcx>, (self, f, cx) { + ('tcx) ty::TraitPredicate<'tcx>, (self, cx) { debug { - write!(f, "TraitPredicate({:?})", - self.trait_ref) + print!(cx, write("TraitPredicate({:?})", + self.trait_ref)) } display { - print!(f, cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + print!(cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) } } } define_print! { - ('tcx) ty::ProjectionPredicate<'tcx>, (self, f, cx) { + ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) { debug { - print!(f, cx, + print!(cx, write("ProjectionPredicate("), print(self.projection_ty), write(", "), @@ -1483,71 +1473,73 @@ define_print! { write(")")) } display { - print!(f, cx, print(self.projection_ty), write(" == "), print(self.ty)) + print!(cx, print(self.projection_ty), write(" == "), print(self.ty)) } } } define_print! { - ('tcx) ty::ProjectionTy<'tcx>, (self, f, cx) { + ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { display { - cx.parameterized(f, self.item_def_id, self.substs, iter::empty()) + cx.parameterized(self.item_def_id, self.substs, iter::empty()) } } } define_print! { - () ty::ClosureKind, (self, f, cx) { + () ty::ClosureKind, (self, cx) { display { match *self { - ty::ClosureKind::Fn => write!(f, "Fn"), - ty::ClosureKind::FnMut => write!(f, "FnMut"), - ty::ClosureKind::FnOnce => write!(f, "FnOnce"), + ty::ClosureKind::Fn => print!(cx, write("Fn")), + ty::ClosureKind::FnMut => print!(cx, write("FnMut")), + ty::ClosureKind::FnOnce => print!(cx, write("FnOnce")), } } } } define_print! { - ('tcx) ty::Predicate<'tcx>, (self, f, cx) { + ('tcx) ty::Predicate<'tcx>, (self, cx) { display { match *self { - ty::Predicate::Trait(ref data) => data.print(f, cx), - ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx), - ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx), - ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx), - ty::Predicate::Projection(ref predicate) => predicate.print(f, cx), - ty::Predicate::WellFormed(ty) => print!(f, cx, print(ty), write(" well-formed")), + ty::Predicate::Trait(ref data) => data.print(cx), + ty::Predicate::Subtype(ref predicate) => predicate.print(cx), + ty::Predicate::RegionOutlives(ref predicate) => predicate.print(cx), + ty::Predicate::TypeOutlives(ref predicate) => predicate.print(cx), + ty::Predicate::Projection(ref predicate) => predicate.print(cx), + ty::Predicate::WellFormed(ty) => print!(cx, print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { - write!(f, "the trait `{}` is object-safe", cx.tcx.item_path_str(trait_def_id)) + print!(cx, write("the trait `{}` is object-safe", + cx.tcx.item_path_str(trait_def_id))) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { - write!(f, "the closure `{}` implements the trait `{}`", - cx.tcx.item_path_str(closure_def_id), kind) + print!(cx, write("the closure `{}` implements the trait `{}`", + cx.tcx.item_path_str(closure_def_id), kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "the constant `")?; - cx.parameterized(f, def_id, substs, iter::empty())?; - write!(f, "` can be evaluated") + print!(cx, write("the constant `"))?; + cx.parameterized(def_id, substs, iter::empty())?; + print!(cx, write("` can be evaluated")) } } } debug { match *self { - ty::Predicate::Trait(ref a) => a.print(f, cx), - ty::Predicate::Subtype(ref pair) => pair.print(f, cx), - ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx), - ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx), - ty::Predicate::Projection(ref pair) => pair.print(f, cx), - ty::Predicate::WellFormed(ty) => ty.print(f, cx), + ty::Predicate::Trait(ref a) => a.print(cx), + ty::Predicate::Subtype(ref pair) => pair.print(cx), + ty::Predicate::RegionOutlives(ref pair) => pair.print(cx), + ty::Predicate::TypeOutlives(ref pair) => pair.print(cx), + ty::Predicate::Projection(ref pair) => pair.print(cx), + ty::Predicate::WellFormed(ty) => ty.print(cx), ty::Predicate::ObjectSafe(trait_def_id) => { - write!(f, "ObjectSafe({:?})", trait_def_id) + print!(cx, write("ObjectSafe({:?})", trait_def_id)) } ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) + print!(cx, write("ClosureKind({:?}, {:?}, {:?})", + closure_def_id, closure_substs, kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + print!(cx, write("ConstEvaluatable({:?}, {:?})", def_id, substs)) } } } @@ -1555,19 +1547,19 @@ define_print! { } define_print! { - ('tcx) Kind<'tcx>, (self, f, cx) { + ('tcx) Kind<'tcx>, (self, cx) { display { match self.unpack() { - UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), - UnpackedKind::Type(ty) => print!(f, cx, print(ty)), - UnpackedKind::Const(ct) => print!(f, cx, print(ct)), + UnpackedKind::Lifetime(lt) => print!(cx, print(lt)), + UnpackedKind::Type(ty) => print!(cx, print(ty)), + UnpackedKind::Const(ct) => print!(cx, print(ct)), } } debug { match self.unpack() { - UnpackedKind::Lifetime(lt) => print!(f, cx, print(lt)), - UnpackedKind::Type(ty) => print!(f, cx, print(ty)), - UnpackedKind::Const(ct) => print!(f, cx, print(ct)), + UnpackedKind::Lifetime(lt) => print!(cx, print(lt)), + UnpackedKind::Type(ty) => print!(cx, print(ty)), + UnpackedKind::Const(ct) => print!(cx, print(ct)), } } } diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 2b70141894be9..466cf40a15795 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -4,6 +4,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 56ef15b12a0a9..6bd9b159775e3 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -225,8 +225,7 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { item_path::with_forced_absolute_paths(|| { - let mut cx = PrintCx::new(tcx); - SymbolPathPrinter::print_item_path(&mut cx, def_id).into_interned() + PrintCx::new(tcx, SymbolPathPrinter).print_item_path(def_id).into_interned() }) } @@ -401,17 +400,21 @@ struct SymbolPathPrinter; impl ItemPathPrinter for SymbolPathPrinter { type Path = SymbolPath; - fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { - let mut path = SymbolPath::new(cx.tcx); - path.push(&cx.tcx.original_crate_name(cnum).as_str()); + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + let mut path = SymbolPath::new(self.tcx); + path.push(&self.tcx.original_crate_name(cnum).as_str()); path } - fn path_impl(cx: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { - let mut path = SymbolPath::new(cx.tcx); + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { + let mut path = SymbolPath::new(self.tcx); path.push(text); path } - fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { path.push(text); path } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ed7f1bbe7e6ac..d321697f713f8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4233,20 +4233,23 @@ where F: Fn(DefId) -> Def { impl ItemPathPrinter for AbsolutePathPrinter { type Path = Vec; - fn path_crate(cx: &mut PrintCx<'_, '_, '_>, cnum: CrateNum) -> Self::Path { - vec![cx.tcx.original_crate_name(cnum).to_string()] + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + vec![self.tcx.original_crate_name(cnum).to_string()] } - fn path_impl(_: &mut PrintCx<'_, '_, '_>, text: &str) -> Self::Path { + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { vec![text.to_string()] } - fn path_append(mut path: Self::Path, text: &str) -> Self::Path { + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { path.push(text.to_string()); path } } - let mut cx = PrintCx::new(tcx); - let names = AbsolutePathPrinter::print_item_path(&mut cx, def_id); + let names = PrintCx::new(tcx, AbsolutePathPrinter).print_item_path(def_id); hir::Path { span: DUMMY_SP, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f11e268b9092c..58ba827ee05f3 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -5,6 +5,7 @@ #![feature(bind_by_move_pattern_guards)] #![feature(rustc_private)] +#![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(nll)] From 238616813974babc53cb85aaa8e102df119d7f0f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Dec 2018 15:12:48 +0200 Subject: [PATCH 096/157] rustc: explicitly pass the namespace to PrintCx::parameterized. --- src/librustc/mir/mod.rs | 4 +- src/librustc/ty/instance.rs | 3 +- src/librustc/util/ppaux.rs | 79 +++++++++++++++------------ src/test/mir-opt/basic_assignment.rs | 2 +- src/test/mir-opt/match_false_edges.rs | 6 +- src/test/mir-opt/storage_ranges.rs | 2 +- 6 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 7d2050a7c68a8..ec42809ff6569 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2,7 +2,7 @@ //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html -use crate::hir::def::CtorKind; +use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def_id::DefId; use crate::hir::{self, HirId, InlineAsm}; use crate::mir::interpret::{ConstValue, EvalErrorKind, Scalar}; @@ -2405,7 +2405,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, variant_def.did, substs)?; + ppaux::parameterized(fmt, variant_def.did, substs, Namespace::ValueNS)?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 0a49dea7ec1bc..fd0b97e98a3f9 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,4 +1,5 @@ use crate::hir::Unsafety; +use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; use crate::traits; @@ -175,7 +176,7 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ppaux::parameterized(f, self.def_id(), self.substs)?; + ppaux::parameterized(f, self.def_id(), self.substs, Namespace::ValueNS)?; match self.def { InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 780ff8a61e41c..94560606cad2a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,3 +1,4 @@ +use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::hir::map::definitions::DefPathData; use crate::middle::region; @@ -285,26 +286,12 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { fn parameterized( &mut self, - mut def_id: DefId, + def_id: DefId, substs: SubstsRef<'tcx>, + ns: Namespace, projections: impl Iterator>, ) -> fmt::Result { - let mut key = self.tcx.def_key(def_id); - let is_value_ns = match key.disambiguated_data.data { - DefPathData::ValueNs(_) | - DefPathData::EnumVariant(_) => true, - - // Skip `StructCtor` so that `Struct::` will be printed, - // instead of the less pretty `Struct::{{constructor}}`. - DefPathData::StructCtor => { - def_id.index = key.parent.unwrap(); - key = self.tcx.def_key(def_id); - true - } - - _ => false, - }; - + let key = self.tcx.def_key(def_id); let generics = self.tcx.generics_of(def_id); if let Some(parent_def_id) = generics.parent { @@ -315,13 +302,20 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { parent_generics.has_self && parent_generics.parent_count == 0; if parent_has_own_self { print!(self, write("<"), print_display(substs.type_at(0)), write(" as "))?; - } - self.parameterized(parent_def_id, substs, iter::empty())?; - if parent_has_own_self { + self.parameterized(parent_def_id, substs, Namespace::TypeNS, iter::empty())?; print!(self, write(">"))?; + } else { + self.parameterized(parent_def_id, substs, ns, iter::empty())?; } - print!(self, write("::{}", key.disambiguated_data.data.as_interned_str()))?; + // Skip `::{{constructor}}` on tuple/unit structs. + match key.disambiguated_data.data { + DefPathData::StructCtor => {} + + _ => { + print!(self, write("::{}", key.disambiguated_data.data.as_interned_str()))?; + } + } } else { // Try to print `impl`s more like how you'd refer to their associated items. if let DefPathData::Impl = key.disambiguated_data.data { @@ -352,7 +346,7 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { } }; - let start = if is_value_ns { "::<" } else { "<" }; + let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; let has_own_self = generics.has_self && generics.parent_count == 0; let params = &generics.params[has_own_self as usize..]; @@ -496,10 +490,15 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { } } -pub fn parameterized(f: &mut F, did: DefId, substs: SubstsRef<'_>) -> fmt::Result { +pub fn parameterized( + f: &mut F, + did: DefId, + substs: SubstsRef<'_>, + ns: Namespace, +) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.parameterized(did, substs, iter::empty()) + cx.parameterized(did, substs, ns, iter::empty()) }) } @@ -538,6 +537,7 @@ define_print! { cx.parameterized( principal.def_id, principal.substs, + Namespace::TypeNS, self.projection_bounds(), )?; } @@ -663,7 +663,7 @@ define_print! { let trait_ref = *ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) .skip_binder(); - cx.parameterized(trait_ref.def_id, trait_ref.substs, iter::empty()) + cx.parameterized(trait_ref.def_id, trait_ref.substs, Namespace::TypeNS, iter::empty()) } debug { self.print_display(cx) @@ -1112,12 +1112,16 @@ define_print_multi! { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, cx) { display { - cx.parameterized(self.def_id, self.substs, iter::empty()) + cx.parameterized(self.def_id, self.substs, Namespace::TypeNS, iter::empty()) } debug { - print!(cx, write("<"), print(self.self_ty()), write(" as "))?; - cx.parameterized(self.def_id, self.substs, iter::empty())?; - print!(cx, write(">")) + print!(cx, + write("<"), + print(self.self_ty()), + write(" as "), + print_display(self), + write(">") + ) } } } @@ -1163,7 +1167,7 @@ define_print! { FnDef(def_id, substs) => { let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); print!(cx, print(sig), write(" {{"))?; - cx.parameterized(def_id, substs, iter::empty())?; + cx.parameterized(def_id, substs, Namespace::ValueNS, iter::empty())?; print!(cx, write("}}")) } FnPtr(ref bare_fn) => { @@ -1185,7 +1189,9 @@ define_print! { ty::BoundTyKind::Param(p) => print!(cx, write("{}", p)), } } - Adt(def, substs) => cx.parameterized(def.did, substs, iter::empty()), + Adt(def, substs) => { + cx.parameterized(def.did, substs, Namespace::TypeNS, iter::empty()) + } Dynamic(data, r) => { let print_r = r.display_outputs_anything(cx); if print_r { @@ -1199,7 +1205,12 @@ define_print! { Ok(()) } Foreign(def_id) => { - cx.parameterized(def_id, subst::InternalSubsts::empty(), iter::empty()) + cx.parameterized( + def_id, + subst::InternalSubsts::empty(), + Namespace::TypeNS, + iter::empty(), + ) } Projection(ref data) => data.print(cx), UnnormalizedProjection(ref data) => { @@ -1481,7 +1492,7 @@ define_print! { define_print! { ('tcx) ty::ProjectionTy<'tcx>, (self, cx) { display { - cx.parameterized(self.item_def_id, self.substs, iter::empty()) + cx.parameterized(self.item_def_id, self.substs, Namespace::TypeNS, iter::empty()) } } } @@ -1518,7 +1529,7 @@ define_print! { } ty::Predicate::ConstEvaluatable(def_id, substs) => { print!(cx, write("the constant `"))?; - cx.parameterized(def_id, substs, iter::empty())?; + cx.parameterized(def_id, substs, Namespace::ValueNS, iter::empty())?; print!(cx, write("` can be evaluated")) } } diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index 1bbbe67a12cb8..3ce43cc4a224f 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -35,7 +35,7 @@ fn main() { // _2 = move _3; // StorageDead(_3); // StorageLive(_4); -// _4 = std::option::Option>::None; +// _4 = std::option::Option::>::None; // FakeRead(ForLet, _4); // AscribeUserType(_4, o, UserTypeProjection { base: UserType(1), projs: [] }); // StorageLive(_5); diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index ab6de71d2894d..9eeef8570a37a 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -42,7 +42,7 @@ fn main() { // START rustc.full_tested_match.QualifyAndPromoteConstants.after.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 42i32,); +// _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb7]; @@ -111,7 +111,7 @@ fn main() { // START rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 42i32,); +// _2 = std::option::Option::::Some(const 42i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb7]; @@ -180,7 +180,7 @@ fn main() { // START rustc.main.QualifyAndPromoteConstants.before.mir // bb0: { // ... -// _2 = std::option::Option::Some(const 1i32,); +// _2 = std::option::Option::::Some(const 1i32,); // FakeRead(ForMatchedPlace, _2); // _3 = discriminant(_2); // switchInt(move _3) -> [1isize: bb2, otherwise: bb3]; diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index a5d6ced2b1772..9a22f57116ed8 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -18,7 +18,7 @@ fn main() { // StorageLive(_4); // StorageLive(_5); // _5 = _1; -// _4 = std::option::Option::Some(move _5,); +// _4 = std::option::Option::::Some(move _5,); // StorageDead(_5); // _3 = &_4; // FakeRead(ForLet, _3); From ed2be6fa89428b6c0a43e41a8906d29bc78f62d0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Dec 2018 18:28:29 +0200 Subject: [PATCH 097/157] rustc: move the FORCE_IMPL_FILENAME_LINE handling into LocalPathPrinter. --- src/librustc/ty/item_path.rs | 52 ++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0612401ca25db..87859ac00c396 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -91,7 +91,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } DefPathData::Impl => { - self.default_print_impl_path(def_id) + self.print_impl_path(def_id) } // Unclear if there is any value in distinguishing these. @@ -132,18 +132,6 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = !impl_def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - return self.default_print_impl_path_fallback(impl_def_id); - } - // Decide whether to print the parent path for the impl. // Logically, since impls are global, it's never needed, but // users may find it useful. Currently, we omit the parent if @@ -210,19 +198,6 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } } } - - fn default_print_impl_path_fallback(&mut self, impl_def_id: DefId) -> P::Path { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` - let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); - let path = self.print_item_path(parent_def_id); - let hir_id = self.tcx.hir().as_local_hir_id(impl_def_id).unwrap(); - let item = self.tcx.hir().expect_item_by_hir_id(hir_id); - let span_str = self.tcx.sess.source_map().span_to_string(item.span); - self.path_append(path, &format!("", span_str)) - } } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { @@ -291,6 +266,9 @@ pub trait ItemPathPrinter: Sized { fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path { self.default_print_item_path(def_id) } + fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path { + self.default_print_impl_path(impl_def_id) + } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; @@ -470,6 +448,28 @@ impl ItemPathPrinter for LocalPathPrinter { self.try_print_visible_item_path(def_id) .unwrap_or_else(|| self.default_print_item_path(def_id)) } + fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = !impl_def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` + let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); + let path = self.print_item_path(parent_def_id); + let span = self.tcx.def_span(impl_def_id); + return self.path_append(path, &format!("", span)); + } + + self.default_print_impl_path(impl_def_id) + } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { if cnum == LOCAL_CRATE { From 9445f2bf719d4f6064d9d79349e21822c6293d3c Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:37:53 +0530 Subject: [PATCH 098/157] Improved test output for liballoc/str --- src/liballoc/tests/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..f465d67dc9368 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -7,7 +7,7 @@ fn test_le() { assert!("" <= ""); assert!("" <= "foo"); assert!("foo" <= "foo"); - assert!("foo" != "bar"); + assert_ne!("foo", "bar"); } #[test] From 6d73a8f753fb68bb7da4b2c35908d0512a981db9 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:07 +0530 Subject: [PATCH 099/157] Improved test output for libcore/cell --- src/libcore/tests/cell.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..085d81a36d185 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -5,15 +5,15 @@ use std::mem::drop; #[test] fn smoketest_cell() { let x = Cell::new(10); - assert!(x == Cell::new(10)); - assert!(x.get() == 10); + assert_eq!(x, Cell::new(10)); + assert_eq!(x.get(), 10); x.set(20); - assert!(x == Cell::new(20)); - assert!(x.get() == 20); + assert_eq!(x, Cell::new(20)); + assert_eq!(x.get(), 20); let y = Cell::new((30, 40)); - assert!(y == Cell::new((30, 40))); - assert!(y.get() == (30, 40)); + assert_eq!(y, Cell::new((30, 40))); + assert_eq!(y.get(), (30, 40)); } #[test] From 8ff2198bc7a8a0a986e0df930422d9aa63b1bcd3 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:23 +0530 Subject: [PATCH 100/157] Improved test output for libcore/ops --- src/libcore/tests/ops.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 401644e120d16..78cf07119e729 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -7,11 +7,11 @@ fn test_range() { let r = Range { start: 2, end: 10 }; let mut count = 0; for (i, ri) in r.enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 10); count += 1; } - assert!(count == 8); + assert_eq!(count, 8); } #[test] @@ -19,11 +19,11 @@ fn test_range_from() { let r = RangeFrom { start: 2 }; let mut count = 0; for (i, ri) in r.take(10).enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 12); count += 1; } - assert!(count == 10); + assert_eq!(count, 10); } #[test] From 2f5238867186b7e30a3baff0086b25c9cf7407b7 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:37 +0530 Subject: [PATCH 101/157] Improved test output for libcore/num/int_macros --- src/libcore/tests/num/int_macros.rs | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 5c6ee8f8ba038..4881f79ec248a 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -12,7 +12,7 @@ mod tests { fn test_overflows() { assert!(MAX > 0); assert!(MIN <= 0); - assert!(MIN + MAX + 1 == 0); + assert_eq!(MIN + MAX + 1, 0); } #[test] @@ -22,22 +22,22 @@ mod tests { #[test] fn test_rem_euclid() { - assert!((-1 as $T).rem_euclid(MIN) == MAX); + assert_eq!((-1 as $T).rem_euclid(MIN), MAX); } #[test] pub fn test_abs() { - assert!((1 as $T).abs() == 1 as $T); - assert!((0 as $T).abs() == 0 as $T); - assert!((-1 as $T).abs() == 1 as $T); + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); } #[test] fn test_signum() { - assert!((1 as $T).signum() == 1 as $T); - assert!((0 as $T).signum() == 0 as $T); - assert!((-0 as $T).signum() == 0 as $T); - assert!((-1 as $T).signum() == -1 as $T); + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); } #[test] @@ -58,12 +58,12 @@ mod tests { #[test] fn test_bitwise_operators() { - assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); - assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); - assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); - assert!(0b1110 as $T == (0b0111 as $T).shl(1)); - assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not()); + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); } const A: $T = 0b0101100; @@ -75,17 +75,17 @@ mod tests { #[test] fn test_count_ones() { - assert!(A.count_ones() == 3); - assert!(B.count_ones() == 2); - assert!(C.count_ones() == 5); + assert_eq!(A.count_ones(), 3); + assert_eq!(B.count_ones(), 2); + assert_eq!(C.count_ones(), 5); } #[test] fn test_count_zeros() { let bits = mem::size_of::<$T>() * 8; - assert!(A.count_zeros() == bits as u32 - 3); - assert!(B.count_zeros() == bits as u32 - 2); - assert!(C.count_zeros() == bits as u32 - 5); + assert_eq!(A.count_zeros(), bits as u32 - 3); + assert_eq!(B.count_zeros(), bits as u32 - 2); + assert_eq!(C.count_zeros(), bits as u32 - 5); } #[test] @@ -148,9 +148,9 @@ mod tests { #[test] fn test_signed_checked_div() { - assert!((10 as $T).checked_div(2) == Some(5)); - assert!((5 as $T).checked_div(0) == None); - assert!(isize::MIN.checked_div(-1) == None); + assert_eq!((10 as $T).checked_div(2), Some(5)); + assert_eq!((5 as $T).checked_div(0), None); + assert_eq!(isize::MIN.checked_div(-1), None); } #[test] From e9e5a75fd2bc5f7908642129aa462ee15ce17a3b Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:51 +0530 Subject: [PATCH 102/157] Improved test output for estr-slice --- src/test/run-pass/array-slice-vec/estr-slice.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs index 02b88f6a7abfc..cd2c17220655a 100644 --- a/src/test/run-pass/array-slice-vec/estr-slice.rs +++ b/src/test/run-pass/array-slice-vec/estr-slice.rs @@ -14,7 +14,7 @@ pub fn main() { let z : &str = "thing"; assert_eq!(v, x); - assert!(x != z); + assert_ne!(x, z); let a = "aaaa"; let b = "bbbb"; @@ -26,7 +26,7 @@ pub fn main() { assert!(a < b); assert!(a <= b); - assert!(a != b); + assert_ne!(a, b); assert!(b >= a); assert!(b > a); @@ -34,7 +34,7 @@ pub fn main() { assert!(a < c); assert!(a <= c); - assert!(a != c); + assert_ne!(a, c); assert!(c >= a); assert!(c > a); @@ -42,7 +42,7 @@ pub fn main() { assert!(c < cc); assert!(c <= cc); - assert!(c != cc); + assert_ne!(c, cc); assert!(cc >= c); assert!(cc > c); From 3e1cef700753ef4802c244f7e48d59de5d4324dd Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 05:01:06 +0200 Subject: [PATCH 103/157] rustc: pass Option<&Substs> and Namespace around in ty::item_path. --- src/librustc/ty/item_path.rs | 137 +++++++++++++----- src/librustc/util/ppaux.rs | 20 +-- src/librustc_codegen_utils/symbol_names.rs | 5 +- src/librustdoc/clean/mod.rs | 5 +- src/test/pretty/issue-4264.pp | 34 ++--- src/test/ui/bad/bad-sized.stderr | 2 +- ...gate-unleash_the_miri_inside_of_you.stderr | 2 +- src/test/ui/hygiene/impl_items.rs | 2 +- src/test/ui/hygiene/impl_items.stderr | 2 +- src/test/ui/issues/issue-17651.stderr | 2 +- src/test/ui/issues/issue-22638.rs | 2 +- src/test/ui/issues/issue-22638.stderr | 2 +- src/test/ui/issues/issue-24322.stderr | 2 +- src/test/ui/issues/issue-29124.rs | 2 +- src/test/ui/issues/issue-29124.stderr | 2 +- .../issue-37311.stderr | 2 +- src/test/ui/issues/issue-39559-2.stderr | 4 +- .../associated-item-privacy-inherent.rs | 6 +- .../associated-item-privacy-inherent.stderr | 6 +- .../ui/privacy/private-inferred-type-3.rs | 2 +- .../ui/privacy/private-inferred-type-3.stderr | 2 +- src/test/ui/privacy/private-inferred-type.rs | 2 +- .../ui/privacy/private-inferred-type.stderr | 2 +- .../ui/qualified/qualified-path-params.stderr | 2 +- src/test/ui/symbol-names/impl1.rs | 2 +- src/test/ui/symbol-names/impl1.stderr | 2 +- 26 files changed, 159 insertions(+), 94 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 87859ac00c396..d9a8deb80e46a 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -1,8 +1,10 @@ +use crate::hir::def::Namespace; use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::ty::print::PrintCx; +use crate::ty::subst::{Subst, Substs}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use ty::print::PrintCx; use syntax::ast; use syntax::symbol::{keywords, Symbol}; @@ -54,18 +56,48 @@ pub fn with_crate_prefix R, R>(f: F) -> R { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { + // HACK(eddyb) get rid of `item_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + /// Returns a string identifying this `DefId`. This string is /// suitable for user output. It is relative to the current crate /// root, unless with_forced_absolute_paths was used. - pub fn item_path_str(self, def_id: DefId) -> String { - debug!("item_path_str: def_id={:?}", def_id); + pub fn item_path_str_with_substs_and_ns( + self, + def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> String { + debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); if FORCE_ABSOLUTE.with(|force| force.get()) { - PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id) + PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, substs, ns) } else { - PrintCx::new(self, LocalPathPrinter).print_item_path(def_id) + PrintCx::new(self, LocalPathPrinter).print_item_path(def_id, substs, ns) } } + /// Returns a string identifying this def-id. This string is + /// suitable for user output. It is relative to the current crate + /// root, unless with_forced_absolute_paths was used. + pub fn item_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + self.item_path_str_with_substs_and_ns(def_id, None, ns) + } + /// Returns a string identifying this local node-id. pub fn node_path_str(self, id: ast::NodeId) -> String { self.item_path_str(self.hir().local_def_id(id)) @@ -75,13 +107,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String { debug!("absolute_item_path_str: def_id={:?}", def_id); - PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id) + let ns = self.guess_def_namespace(def_id); + PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, None, ns) } } impl PrintCx<'a, 'gcx, 'tcx, P> { - pub fn default_print_item_path(&mut self, def_id: DefId) -> P::Path { - debug!("default_print_item_path: def_id={:?}", def_id); + pub fn default_print_item_path( + &mut self, + def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> P::Path { + debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); let key = self.tcx.def_key(def_id); debug!("default_print_item_path: key={:?}", key); match key.disambiguated_data.data { @@ -91,7 +129,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } DefPathData::Impl => { - self.print_impl_path(def_id) + self.print_impl_path(def_id, substs, ns) } // Unclear if there is any value in distinguishing these. @@ -117,18 +155,23 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { let parent_did = self.tcx.parent_def_id(def_id).unwrap(); - let path = self.print_item_path(parent_did); + let path = self.print_item_path(parent_did, None, ns); self.path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); - self.print_item_path(parent_def_id) + self.print_item_path(parent_def_id, substs, ns) } } } - fn default_print_impl_path(&mut self, impl_def_id: DefId) -> P::Path { + fn default_print_impl_path( + &mut self, + impl_def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> P::Path { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); @@ -137,13 +180,19 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let self_ty = self.tcx.type_of(impl_def_id); + let mut self_ty = self.tcx.type_of(impl_def_id); + if let Some(substs) = substs { + self_ty = self_ty.subst(self.tcx, substs); + } let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, Some(ty_def_id) => self.tcx.parent_def_id(ty_def_id) == Some(parent_def_id), }; - let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); + let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); + if let Some(substs) = substs { + impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); + } let in_trait_mod = match impl_trait_ref { None => false, Some(trait_ref) => self.tcx.parent_def_id(trait_ref.def_id) == Some(parent_def_id), @@ -153,7 +202,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = self.print_item_path(parent_def_id); + let path = self.print_item_path(parent_def_id, None, ns); if let Some(trait_ref) = impl_trait_ref { return self.path_append(path, &format!("", trait_ref, self_ty)); } else { @@ -174,15 +223,14 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // anything other than a simple path. match self_ty.sty { ty::Adt(adt_def, substs) => { - // FIXME(eddyb) always print without <> here. - if substs.types().next().is_none() { // ignore regions - self.print_item_path(adt_def.did) - } else { - self.path_impl(&format!("<{}>", self_ty)) - } + // FIXME(eddyb) this should recurse to build the path piecewise. + // self.print_item_path(adt_def.did, Some(substs), ns) + let mut s = String::new(); + crate::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap(); + self.path_impl(&s) } - ty::Foreign(did) => self.print_item_path(did), + ty::Foreign(did) => self.print_item_path(did, None, ns), ty::Bool | ty::Char | @@ -263,11 +311,21 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { pub trait ItemPathPrinter: Sized { type Path; - fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path { - self.default_print_item_path(def_id) + fn print_item_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> Self::Path { + self.default_print_item_path(def_id, substs, ns) } - fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path { - self.default_print_impl_path(impl_def_id) + fn print_impl_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> Self::Path { + self.default_print_impl_path(impl_def_id, substs, ns) } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; @@ -312,6 +370,7 @@ impl LocalPathPrinter { fn try_print_visible_item_path( self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId, + ns: Namespace, ) -> Option<::Path> { debug!("try_print_visible_item_path: def_id={:?}", def_id); @@ -343,7 +402,7 @@ impl LocalPathPrinter { }) => { debug!("try_print_visible_item_path: def_id={:?}", def_id); let path = if !span.is_dummy() { - self.print_item_path(def_id) + self.print_item_path(def_id, None, ns) } else { self.path_crate(cnum) }; @@ -376,7 +435,7 @@ impl LocalPathPrinter { } let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = self.try_print_visible_item_path(visible_parent)?; + let path = self.try_print_visible_item_path(visible_parent, ns)?; let actual_parent = self.tcx.parent(def_id); let data = cur_def_key.disambiguated_data.data; @@ -444,11 +503,21 @@ impl LocalPathPrinter { impl ItemPathPrinter for LocalPathPrinter { type Path = String; - fn print_item_path(self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId) -> Self::Path { - self.try_print_visible_item_path(def_id) - .unwrap_or_else(|| self.default_print_item_path(def_id)) + fn print_item_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> Self::Path { + self.try_print_visible_item_path(def_id, ns) + .unwrap_or_else(|| self.default_print_item_path(def_id, substs, ns)) } - fn print_impl_path(self: &mut PrintCx<'_, '_, '_, Self>, impl_def_id: DefId) -> Self::Path { + fn print_impl_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_def_id: DefId, + substs: Option<&Substs<'tcx>>, + ns: Namespace, + ) -> Self::Path { // Always use types for non-local impls, where types are always // available, and filename/line-number is mostly uninteresting. let use_types = !impl_def_id.is_local() || { @@ -463,12 +532,12 @@ impl ItemPathPrinter for LocalPathPrinter { // only occur very early in the compiler pipeline. // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); - let path = self.print_item_path(parent_def_id); + let path = self.print_item_path(parent_def_id, None, ns); let span = self.tcx.def_span(impl_def_id); return self.path_append(path, &format!("", span)); } - self.default_print_impl_path(impl_def_id) + self.default_print_impl_path(impl_def_id, substs, ns) } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 94560606cad2a..092255129f4ee 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -317,23 +317,15 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { } } } else { - // Try to print `impl`s more like how you'd refer to their associated items. + // FIXME(eddyb) recurse through printing a path via `self`, instead + // instead of using the `tcx` method that produces a `String`. + print!(self, write("{}", + self.tcx.item_path_str_with_substs_and_ns(def_id, Some(substs), ns)))?; + + // For impls, the above call already prints relevant generics args. if let DefPathData::Impl = key.disambiguated_data.data { - if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { - // HACK(eddyb) this is in lieu of more specific disambiguation. - print!(self, write("{}", self.tcx.item_path_str(def_id)))?; - - let trait_ref = trait_ref.subst(self.tcx, substs); - print!(self, print_debug(trait_ref))?; - } else { - let self_ty = self.tcx.type_of(def_id).subst(self.tcx, substs); - // FIXME(eddyb) omit the <> where possible. - print!(self, write("<"), print(self_ty), write(">"))?; - } return Ok(()); } - - print!(self, write("{}", self.tcx.item_path_str(def_id)))?; } let mut empty = true; diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 6bd9b159775e3..a7771f3da18ee 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -87,6 +87,7 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. +use rustc::hir::def::Namespace; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; @@ -225,7 +226,9 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { item_path::with_forced_absolute_paths(|| { - PrintCx::new(tcx, SymbolPathPrinter).print_item_path(def_id).into_interned() + PrintCx::new(tcx, SymbolPathPrinter) + .print_item_path(def_id, None, Namespace::ValueNS) + .into_interned() }) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d321697f713f8..6714866369efa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -18,7 +18,7 @@ use rustc::middle::lang_items; use rustc::middle::stability; use rustc::mir::interpret::GlobalId; use rustc::hir::{self, GenericArg, HirVec}; -use rustc::hir::def::{self, Def, CtorKind}; +use rustc::hir::def::{self, Def, CtorKind, Namespace}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind}; @@ -4249,7 +4249,8 @@ where F: Fn(DefId) -> Def { } } - let names = PrintCx::new(tcx, AbsolutePathPrinter).print_item_path(def_id); + let names = PrintCx::new(tcx, AbsolutePathPrinter) + .print_item_path(def_id, None, Namespace::TypeNS); hir::Path { span: DUMMY_SP, diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index b529beba78367..ad663412e7776 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -32,27 +32,27 @@ (($crate::fmt::format as for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<$crate::fmt::Arguments>::new_v1 as - fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test" + fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test" + as + &'static str)] as - &'static str)] + [&str; 1]) as - [&str; 1]) - as - &[&str; 1]), - (&(match (() + &[&str; 1]), + (&(match (() + as + ()) + { + () + => + ([] as - ()) - { - () - => - ([] - as - [std::fmt::ArgumentV1<'_>; 0]), - } + [std::fmt::ArgumentV1<'_>; 0]), + } + as + [std::fmt::ArgumentV1<'_>; 0]) as - [std::fmt::ArgumentV1<'_>; 0]) - as - &[std::fmt::ArgumentV1<'_>; 0])) + &[std::fmt::ArgumentV1<'_>; 0])) as std::fmt::Arguments<'_>)) as std::string::String); diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr index 9565888dcc022..51b8474555293 100644 --- a/src/test/ui/bad/bad-sized.stderr +++ b/src/test/ui/bad/bad-sized.stderr @@ -22,7 +22,7 @@ LL | let x: Vec = Vec::new(); | = help: the trait `std::marker::Sized` is not implemented for `dyn Trait` = note: to learn more, visit - = note: required by `>::new` + = note: required by `std::vec::Vec::::new` error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr index 1fe3d33322fd1..7ede44c65b83a 100644 --- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr @@ -4,7 +4,7 @@ error[E0493]: destructors cannot be evaluated at compile-time LL | const F: u32 = (U::X, 42).1; | ^^^^^^^^^^ constants cannot evaluate destructors -error: `>::new` is not yet stable as a const fn +error: `std::vec::Vec::::new` is not yet stable as a const fn --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25 | LL | const X: Vec = Vec::new(); diff --git a/src/test/ui/hygiene/impl_items.rs b/src/test/ui/hygiene/impl_items.rs index d628573d51707..37794c6e0773c 100644 --- a/src/test/ui/hygiene/impl_items.rs +++ b/src/test/ui/hygiene/impl_items.rs @@ -9,7 +9,7 @@ mod foo { } pub macro m() { - let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {::f}` is private + let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private } } diff --git a/src/test/ui/hygiene/impl_items.stderr b/src/test/ui/hygiene/impl_items.stderr index 0a273bc98ff61..418c2c73ba157 100644 --- a/src/test/ui/hygiene/impl_items.stderr +++ b/src/test/ui/hygiene/impl_items.stderr @@ -1,4 +1,4 @@ -error: type `for<'r> fn(&'r foo::S) {::f}` is private +error: type `for<'r> fn(&'r foo::S) {foo::S::f}` is private --> $DIR/impl_items.rs:12:23 | LL | let _: () = S.f(); diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr index 72c40ff4b3a0c..ce9af1524b087 100644 --- a/src/test/ui/issues/issue-17651.stderr +++ b/src/test/ui/issues/issue-17651.stderr @@ -6,7 +6,7 @@ LL | (|| Box::new(*(&[0][..])))(); | = help: the trait `std::marker::Sized` is not implemented for `[{integer}]` = note: to learn more, visit - = note: required by `>::new` + = note: required by `std::boxed::Box::::new` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22638.rs b/src/test/ui/issues/issue-22638.rs index ff58c7aaced03..fab24404eba7d 100644 --- a/src/test/ui/issues/issue-22638.rs +++ b/src/test/ui/issues/issue-22638.rs @@ -50,7 +50,7 @@ struct D (Box); impl D { pub fn matches(&self, f: &F) { - //~^ ERROR reached the type-length limit while instantiating `::matches::<[closure + //~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure let &D(ref a) = self; a.matches(f) } diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr index 65483abe5c7f9..aff968f3618c1 100644 --- a/src/test/ui/issues/issue-22638.stderr +++ b/src/test/ui/issues/issue-22638.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `::matches::$CLOSURE` +error: reached the type-length limit while instantiating `D::matches::$CLOSURE` --> $DIR/issue-22638.rs:52:5 | LL | / pub fn matches(&self, f: &F) { diff --git a/src/test/ui/issues/issue-24322.stderr b/src/test/ui/issues/issue-24322.stderr index b284c8cf1172c..def373cf2c0a8 100644 --- a/src/test/ui/issues/issue-24322.stderr +++ b/src/test/ui/issues/issue-24322.stderr @@ -5,7 +5,7 @@ LL | let x: &fn(&B) -> u32 = &B::func; | ^^^^^^^^ expected fn pointer, found fn item | = note: expected type `&for<'r> fn(&'r B) -> u32` - found type `&for<'r> fn(&'r B) -> u32 {::func}` + found type `&for<'r> fn(&'r B) -> u32 {B::func}` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29124.rs b/src/test/ui/issues/issue-29124.rs index 8062045a6c058..1cd3f84f7a227 100644 --- a/src/test/ui/issues/issue-29124.rs +++ b/src/test/ui/issues/issue-29124.rs @@ -13,7 +13,7 @@ fn func() -> Ret { fn main() { Obj::func.x(); - //~^ ERROR no method named `x` found for type `fn() -> Ret {::func}` in the current scope + //~^ ERROR no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope func.x(); //~^ ERROR no method named `x` found for type `fn() -> Ret {func}` in the current scope } diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index 67f188e0588e2..3beb728978884 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `x` found for type `fn() -> Ret {::func}` in the current scope +error[E0599]: no method named `x` found for type `fn() -> Ret {Obj::func}` in the current scope --> $DIR/issue-29124.rs:15:15 | LL | Obj::func.x(); diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index 24b31f43a85aa..c543219041229 100644 --- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&()...` +error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&(), &())), &...` --> $DIR/issue-37311.rs:13:5 | LL | / fn recurse(&self) { diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/issues/issue-39559-2.stderr index ca2f2a5ba2845..700dbe3647497 100644 --- a/src/test/ui/issues/issue-39559-2.stderr +++ b/src/test/ui/issues/issue-39559-2.stderr @@ -8,7 +8,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-39559-2.rs:14:24 | LL | let array: [usize; Dim3::dim()] - | ^^^^^^^^^^^ calling non-const function `::dim` + | ^^^^^^^^^^^ calling non-const function `::dim` error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants --> $DIR/issue-39559-2.rs:17:15 @@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-39559-2.rs:17:15 | LL | = [0; Dim3::dim()]; - | ^^^^^^^^^^^ calling non-const function `::dim` + | ^^^^^^^^^^^ calling non-const function `::dim` error: aborting due to 4 previous errors diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.rs b/src/test/ui/privacy/associated-item-privacy-inherent.rs index b6fd22fa669e0..c3ae920238f18 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.rs +++ b/src/test/ui/privacy/associated-item-privacy-inherent.rs @@ -11,11 +11,11 @@ mod priv_nominal { pub macro mac() { let value = Pub::method; - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private value; - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private Pub.method(); - //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private + //~^ ERROR type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private Pub::CONST; //~^ ERROR associated constant `CONST` is private // let _: Pub::AssocTy; diff --git a/src/test/ui/privacy/associated-item-privacy-inherent.stderr b/src/test/ui/privacy/associated-item-privacy-inherent.stderr index 69be9d2cea6df..6471a7914e103 100644 --- a/src/test/ui/privacy/associated-item-privacy-inherent.stderr +++ b/src/test/ui/privacy/associated-item-privacy-inherent.stderr @@ -1,4 +1,4 @@ -error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private --> $DIR/associated-item-privacy-inherent.rs:13:21 | LL | let value = Pub::method; @@ -7,7 +7,7 @@ LL | let value = Pub::method; LL | priv_nominal::mac!(); | --------------------- in this macro invocation -error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private --> $DIR/associated-item-privacy-inherent.rs:15:9 | LL | value; @@ -16,7 +16,7 @@ LL | value; LL | priv_nominal::mac!(); | --------------------- in this macro invocation -error: type `for<'r> fn(&'r priv_nominal::Pub) {::method}` is private +error: type `for<'r> fn(&'r priv_nominal::Pub) {priv_nominal::Pub::method}` is private --> $DIR/associated-item-privacy-inherent.rs:17:13 | LL | Pub.method(); diff --git a/src/test/ui/privacy/private-inferred-type-3.rs b/src/test/ui/privacy/private-inferred-type-3.rs index d885407a1cd37..39f2e5d4af2aa 100644 --- a/src/test/ui/privacy/private-inferred-type-3.rs +++ b/src/test/ui/privacy/private-inferred-type-3.rs @@ -6,7 +6,7 @@ // error-pattern:type `fn() {::method}` is private // error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private // error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private -// error-pattern:type `for<'r> fn(&'r ext::Pub) {>::priv_method}` is private +// error-pattern:type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private #![feature(decl_macro)] diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr index f8b757ea09820..61cd84762978c 100644 --- a/src/test/ui/privacy/private-inferred-type-3.stderr +++ b/src/test/ui/privacy/private-inferred-type-3.stderr @@ -46,7 +46,7 @@ LL | ext::m!(); | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: type `for<'r> fn(&'r ext::Pub) {>::priv_method}` is private +error: type `for<'r> fn(&'r ext::Pub) {ext::Pub::::priv_method}` is private --> $DIR/private-inferred-type-3.rs:16:5 | LL | ext::m!(); diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs index d98cf5991efeb..d9bb421b53f8c 100644 --- a/src/test/ui/privacy/private-inferred-type.rs +++ b/src/test/ui/privacy/private-inferred-type.rs @@ -47,7 +47,7 @@ mod m { PubTupleStruct; //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private Pub(0u8).priv_method(); - //~^ ERROR type `for<'r> fn(&'r m::Pub) {>::priv_method}` is private + //~^ ERROR type `for<'r> fn(&'r m::Pub) {m::Pub::::priv_method}` is private } trait Trait {} diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr index baa98292b67b5..4d40b6b7cab32 100644 --- a/src/test/ui/privacy/private-inferred-type.stderr +++ b/src/test/ui/privacy/private-inferred-type.stderr @@ -151,7 +151,7 @@ LL | PubTupleStruct; LL | m::m!(); | -------- in this macro invocation -error: type `for<'r> fn(&'r m::Pub) {>::priv_method}` is private +error: type `for<'r> fn(&'r m::Pub) {m::Pub::::priv_method}` is private --> $DIR/private-inferred-type.rs:49:18 | LL | Pub(0u8).priv_method(); diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index 6315ec2e5126b..926b098040f14 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -11,7 +11,7 @@ LL | 0 ..= ::A::f:: => {} | ^^^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types | = note: start type: {integer} - = note: end type: fn() {::f::} + = note: end type: fn() {S::f::} error: aborting due to 2 previous errors diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 97169c33b8cbf..69cd49e39512e 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -5,7 +5,7 @@ mod foo { pub struct Foo { x: u32 } impl Foo { - #[rustc_symbol_name] //~ ERROR _ZN5impl13foo3Foo3bar + #[rustc_symbol_name] //~ ERROR _ZN15impl1..foo..Foo3bar #[rustc_item_path] //~ ERROR item-path(foo::Foo::bar) fn bar() { } } diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr index e4fefeb601fe0..4041eb6b0ba4a 100644 --- a/src/test/ui/symbol-names/impl1.stderr +++ b/src/test/ui/symbol-names/impl1.stderr @@ -1,4 +1,4 @@ -error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E) +error: symbol-name(_ZN15impl1..foo..Foo3bar17hc487d6ec13fe9124E) --> $DIR/impl1.rs:8:9 | LL | #[rustc_symbol_name] From 6ca6c1a6cc2b097c93eee30f0ba5371423e9966f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 06:39:33 +0200 Subject: [PATCH 104/157] rustc_mir: adjust the type_length_limit diagnostic to be more useful. --- src/librustc/ty/item_path.rs | 16 ++++---- src/librustc_mir/monomorphize/collector.rs | 38 +++++++++++++------ src/test/ui/issues/issue-22638.stderr | 2 +- .../issue-37311.stderr | 4 +- src/test/ui/type_length_limit.rs | 2 + src/test/ui/type_length_limit.stderr | 8 +++- 6 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index d9a8deb80e46a..288894f235b71 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -3,7 +3,7 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::print::PrintCx; -use crate::ty::subst::{Subst, Substs}; +use crate::ty::subst::{Subst, SubstsRef}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::{keywords, Symbol}; @@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn item_path_str_with_substs_and_ns( self, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> String { debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); @@ -116,7 +116,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { pub fn default_print_item_path( &mut self, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> P::Path { debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); @@ -169,7 +169,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { fn default_print_impl_path( &mut self, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> P::Path { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); @@ -314,7 +314,7 @@ pub trait ItemPathPrinter: Sized { fn print_item_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.default_print_item_path(def_id, substs, ns) @@ -322,7 +322,7 @@ pub trait ItemPathPrinter: Sized { fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.default_print_impl_path(impl_def_id, substs, ns) @@ -506,7 +506,7 @@ impl ItemPathPrinter for LocalPathPrinter { fn print_item_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.try_print_visible_item_path(def_id, ns) @@ -515,7 +515,7 @@ impl ItemPathPrinter for LocalPathPrinter { fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { // Always use types for non-local impls, where types are always diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bfdf34f3e37e4..307cee5d97217 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -198,6 +198,8 @@ use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; +use std::iter; + #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum MonoItemCollectionMode { Eager, @@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // We include the const length in the type length, as it's better // to be overly conservative. if type_length + const_length > type_length_limit { - // The instance name is already known to be too long for rustc. Use - // `{:.64}` to avoid blasting the user's terminal with thousands of - // lines of type-name. - let instance_name = instance.to_string(); - let msg = format!("reached the type-length limit while instantiating `{:.64}...`", - instance_name); - let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) { - tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg) - } else { - tcx.sess.struct_fatal(&msg) + // The instance name is already known to be too long for rustc. + // Show only the first and last 32 characters to avoid blasting + // the user's terminal with thousands of lines of type-name. + let shrink = |s: String, before: usize, after: usize| { + // An iterator of all byte positions including the end of the string. + let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len())); + + let shrunk = format!( + "{before}...{after}", + before = &s[..positions().nth(before).unwrap_or(s.len())], + after = &s[positions().rev().nth(after).unwrap_or(0)..], + ); + + // Only use the shrunk version if it's really shorter. + // This also avoids the case where before and after slices overlap. + if shrunk.len() < s.len() { + shrunk + } else { + s + } }; - + let msg = format!("reached the type-length limit while instantiating `{}`", + shrink(instance.to_string(), 32, 32)); + let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg); diag.note(&format!( "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate", - type_length_limit * 2)); + type_length)); diag.emit(); tcx.sess.abort_if_errors(); } diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr index aff968f3618c1..b60e1c29ec0ee 100644 --- a/src/test/ui/issues/issue-22638.stderr +++ b/src/test/ui/issues/issue-22638.stderr @@ -8,7 +8,7 @@ LL | | a.matches(f) LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="40000000"]` attribute to your crate + = note: consider adding a `#![type_length_limit="26214380"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index c543219041229..aead415d23f84 100644 --- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&(), &())), &...` +error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse` --> $DIR/issue-37311.rs:13:5 | LL | / fn recurse(&self) { @@ -6,7 +6,7 @@ LL | | (self, self).recurse(); LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate + = note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs index bb54669d37df2..cd15f81a61535 100644 --- a/src/test/ui/type_length_limit.rs +++ b/src/test/ui/type_length_limit.rs @@ -1,3 +1,5 @@ +// ignore-musl +// ignore-x86 // error-pattern: reached the type-length limit while instantiating // Test that the type length limit can be changed. diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr index 910eca075948a..9d07c86356b67 100644 --- a/src/test/ui/type_length_limit.stderr +++ b/src/test/ui/type_length_limit.stderr @@ -1,6 +1,10 @@ -error: reached the type-length limit while instantiating `std::mem::drop::>` + --> $SRC_DIR/libcore/mem.rs:LL:COL | - = note: consider adding a `#![type_length_limit="512"]` attribute to your crate +LL | pub fn drop(_x: T) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: consider adding a `#![type_length_limit="1094"]` attribute to your crate error: aborting due to previous error From f1af5a77a00225bec61c0ae7218031123364b619 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 12:20:59 +0200 Subject: [PATCH 105/157] rustc: remove TyCtxt::parent_def_id in favor of TyCtxt::parent. --- .../error_reporting/nice_region_error/util.rs | 4 ++-- src/librustc/middle/dead.rs | 4 ++-- src/librustc/middle/mem_categorization.rs | 6 ++--- src/librustc/middle/region.rs | 6 ++--- src/librustc/ty/context.rs | 4 ++-- src/librustc/ty/item_path.rs | 22 +++++-------------- src/librustc/ty/mod.rs | 4 ++-- src/librustc/ty/sty.rs | 4 ++-- src/librustc/ty/util.rs | 4 ++-- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 4 ++-- src/librustc_save_analysis/dump_visitor.rs | 6 ++--- src/librustc_save_analysis/lib.rs | 4 ++-- src/librustc_typeck/astconv.rs | 6 ++--- src/librustdoc/clean/mod.rs | 4 ++-- 15 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index 6db1bc382afe9..3ed28a1f98825 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -3,7 +3,7 @@ use crate::hir; use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use crate::ty::{self, Region, Ty}; +use crate::ty::{self, DefIdTree, Region, Ty}; use crate::hir::def_id::DefId; use syntax_pos::Span; @@ -44,7 +44,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let (id, bound_region) = match *anon_region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ref ebr) => ( - self.tcx().parent_def_id(ebr.def_id).unwrap(), + self.tcx().parent(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 94de999c25da8..3da82d728c0c4 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -12,7 +12,7 @@ use crate::hir::CodegenFnAttrFlags; use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::lint; use crate::middle::privacy; -use crate::ty::{self, TyCtxt}; +use crate::ty::{self, DefIdTree, TyCtxt}; use crate::util::nodemap::FxHashSet; use rustc_data_structures::fx::FxHashMap; @@ -78,7 +78,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) | Def::Local(..) | Def::Upvar(..) => {} Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { - if let Some(enum_id) = self.tcx.parent_def_id(variant_id) { + if let Some(enum_id) = self.tcx.parent(variant_id) { self.check_def_id(enum_id); } if !self.ignore_variant_stack.contains(&variant_id) { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ea1c9d8141611..b36d2a57cb3b1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -64,7 +64,7 @@ use crate::hir::Node; use crate::infer::InferCtxt; use crate::hir::def::{Def, CtorKind}; use crate::ty::adjustment; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::fold::TypeFoldable; use crate::ty::layout::VariantIdx; @@ -1133,7 +1133,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { variant_did: DefId) -> cmt<'tcx> { // univariant enums do not need downcasts - let base_did = self.tcx.parent_def_id(variant_did).unwrap(); + let base_did = self.tcx.parent(variant_did).unwrap(); if self.tcx.adt_def(base_did).variants.len() != 1 { let base_ty = base_cmt.ty; let ret = Rc::new(cmt_ { @@ -1275,7 +1275,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { return Err(()) } Def::VariantCtor(def_id, CtorKind::Fn) => { - let enum_def = self.tcx.parent_def_id(def_id).unwrap(); + let enum_def = self.tcx.parent(def_id).unwrap(); (self.cat_downcast_if_needed(pat, cmt, def_id), self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()) } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 42e253273ab3e..2b3802388106a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,7 +17,7 @@ use rustc_macros::HashStable; use syntax::source_map; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use crate::ty::TyCtxt; +use crate::ty::{DefIdTree, TyCtxt}; use crate::ty::query::Providers; use crate::hir; @@ -650,7 +650,7 @@ impl<'tcx> ScopeTree { pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, br: &ty::EarlyBoundRegion) -> Scope { - let param_owner = tcx.parent_def_id(br.def_id).unwrap(); + let param_owner = tcx.parent(br.def_id).unwrap(); let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap(); let scope = tcx.hir().maybe_body_owned_by_by_hir_id(param_owner_id).map(|body_id| { @@ -679,7 +679,7 @@ impl<'tcx> ScopeTree { -> Scope { let param_owner = match fr.bound_region { ty::BoundRegion::BrNamed(def_id, _) => { - tcx.parent_def_id(def_id).unwrap() + tcx.parent(def_id).unwrap() } _ => fr.scope }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ecf1d8a980a8d..1942f98abff17 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -26,7 +26,7 @@ use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; use crate::traits; use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals}; -use crate::ty::{self, Ty, TypeAndMut}; +use crate::ty::{self, DefIdTree, Ty, TypeAndMut}; use crate::ty::{TyS, TyKind, List}; use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst}; use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate}; @@ -1594,7 +1594,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let (suitable_region_binding_scope, bound_region) = match *region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ref ebr) => ( - self.parent_def_id(ebr.def_id).unwrap(), + self.parent(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 288894f235b71..5a15efc2f1142 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -154,13 +154,13 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { data @ DefPathData::ClosureExpr | data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.tcx.parent_def_id(def_id).unwrap(); + let parent_did = self.tcx.parent(def_id).unwrap(); let path = self.print_item_path(parent_did, None, ns); self.path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` - let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); + let parent_def_id = self.tcx.parent(def_id).unwrap(); self.print_item_path(parent_def_id, substs, ns) } } @@ -173,7 +173,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { ns: Namespace, ) -> P::Path { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); - let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); + let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); // Decide whether to print the parent path for the impl. // Logically, since impls are global, it's never needed, but @@ -186,7 +186,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, - Some(ty_def_id) => self.tcx.parent_def_id(ty_def_id) == Some(parent_def_id), + Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), }; let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); @@ -195,7 +195,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } let in_trait_mod = match impl_trait_ref { None => false, - Some(trait_ref) => self.tcx.parent_def_id(trait_ref.def_id) == Some(parent_def_id), + Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), }; if !in_self_mod && !in_trait_mod { @@ -248,16 +248,6 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } } -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - /// Returns the `DefId` of `def_id`'s parent in the def tree. If - /// this returns `None`, then `def_id` represents a crate root or - /// inlined root. - pub fn parent_def_id(self, def_id: DefId) -> Option { - let key = self.def_key(def_id); - key.parent.map(|index| DefId { krate: def_id.krate, index: index }) - } -} - /// As a heuristic, when we see an impl, if we see that the /// 'self type' is a type defined in the same module as the impl, /// we can omit including the path to the impl itself. This @@ -531,7 +521,7 @@ impl ItemPathPrinter for LocalPathPrinter { // pretty printing some span information. This should // only occur very early in the compiler pipeline. // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` - let parent_def_id = self.tcx.parent_def_id(impl_def_id).unwrap(); + let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); let path = self.print_item_path(parent_def_id, None, ns); let span = self.tcx.def_span(impl_def_id); return self.path_append(path, &format!("", span)); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index dbccd60f86b63..ddb3911daeb5d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2893,14 +2893,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef { match def { Def::Variant(did) | Def::VariantCtor(did, ..) => { - let enum_did = self.parent_def_id(did).unwrap(); + let enum_did = self.parent(did).unwrap(); self.adt_def(enum_did).variant_with_id(did) } Def::Struct(did) | Def::Union(did) => { self.adt_def(did).non_enum_variant() } Def::StructCtor(ctor_did, ..) => { - let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent"); + let did = self.parent(ctor_did).expect("struct ctor has no parent"); self.adt_def(did).non_enum_variant() } _ => bug!("expect_variant_def used with unexpected def {:?}", def) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 20acbb5b9c712..dfe87242c7128 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -9,7 +9,7 @@ use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; use rustc_macros::HashStable; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind}; -use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtDef, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable}; use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; use crate::util::captures::Captures; use crate::mir::interpret::{Scalar, Pointer}; @@ -1591,7 +1591,7 @@ impl RegionKind { pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_, '_>) -> DefId { match self { ty::ReEarlyBound(br) => { - tcx.parent_def_id(br.def_id).unwrap() + tcx.parent(br.def_id).unwrap() } ty::ReFree(fr) => fr.scope, _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 422f97b299646..65918a9082102 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -7,7 +7,7 @@ use crate::hir::{self, Node}; use crate::mir::interpret::{sign_extend, truncate}; use crate::ich::NodeIdHashingMode; use crate::traits::{self, ObligationCause}; -use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, UnpackedKind}; use crate::ty::query::TyCtxtAt; use crate::ty::TyKind::*; @@ -563,7 +563,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn closure_base_def_id(self, def_id: DefId) -> DefId { let mut def_id = def_id; while self.is_closure(def_id) { - def_id = self.parent_def_id(def_id).unwrap_or_else(|| { + def_id = self.parent(def_id).unwrap_or_else(|| { bug!("closure {:?} has no parent", def_id); }); } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0bdf44c2ae049..62cfa184430be 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -12,7 +12,7 @@ use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Pla use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, Level}; use rustc_data_structures::bit_set::BitSet; diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 8aa4fdedc18e2..f1a3c682b5384 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -13,7 +13,7 @@ use crate::hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; -use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; +use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{SubstsRef, Kind}; use rustc::ty::layout::VariantIdx; @@ -735,7 +735,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ) -> PatternKind<'tcx> { let mut kind = match def { Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { - let enum_id = self.tcx.parent_def_id(variant_id).unwrap(); + let enum_id = self.tcx.parent(variant_id).unwrap(); let adt_def = self.tcx.adt_def(enum_id); if adt_def.is_enum() { let substs = match ty.sty { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index b82aee7c96ad2..8e68a13e1e1a4 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -17,7 +17,7 @@ use rustc::hir::def::Def as HirDef; use rustc::hir::def_id::DefId; use rustc::session::config::Input; use rustc::span_bug; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use std::path::Path; @@ -1201,7 +1201,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) - .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) + .and_then(|id| self.save_ctxt.tcx.parent(id)) .map(id_from_def_id); match use_tree.kind { @@ -1350,7 +1350,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id) - .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) + .and_then(|id| self.save_ctxt.tcx.parent(id)) .map(id_from_def_id); self.dumper.import( &Access { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d80f3e5ce759c..2aa44a9242ef1 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -20,7 +20,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::privacy::AccessLevels; use rustc::middle::cstore::ExternCrate; use rustc::session::config::{CrateType, Input, OutputType}; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc::{bug, span_bug}; use rustc_typeck::hir_ty_to_ty; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; @@ -763,7 +763,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // This is a reference to a tuple struct where the def_id points // to an invisible constructor function. That is not a very useful // def, so adjust to point to the tuple struct itself. - let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); + let parent_def_id = self.tcx.parent(def_id).unwrap(); Some(Ref { kind: RefKind::Type, span, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fd09ce7f689b5..4e952f972e459 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -12,7 +12,7 @@ use crate::middle::resolve_lifetime as rl; use crate::namespace::Namespace; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc::traits; -use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; +use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef}; use rustc::ty::wf::object_region_bounds; @@ -1452,7 +1452,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { -> Ty<'tcx> { let tcx = self.tcx(); - let trait_def_id = tcx.parent_def_id(item_def_id).unwrap(); + let trait_def_id = tcx.parent(item_def_id).unwrap(); self.prohibit_generics(slice::from_ref(item_segment)); @@ -1621,7 +1621,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else if last >= 1 && segments[last - 1].args.is_some() { // Everything but the penultimate segment should have no // parameters at all. - let enum_def_id = tcx.parent_def_id(def_id).unwrap(); + let enum_def_id = tcx.parent(def_id).unwrap(); (enum_def_id, last - 1) } else { // FIXME: lint here recommending `Enum::<...>::Variant` form diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6714866369efa..e2e2d552ff122 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -21,7 +21,7 @@ use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::def::{self, Def, CtorKind, Namespace}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; -use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind}; +use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::fold::TypeFolder; use rustc::ty::layout::VariantIdx; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -3971,7 +3971,7 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId { Def::ForeignTy(i) => (i, TypeKind::Foreign), Def::Const(i) => (i, TypeKind::Const), Def::Static(i, _) => (i, TypeKind::Static), - Def::Variant(i) => (cx.tcx.parent_def_id(i).expect("cannot get parent def id"), + Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"), TypeKind::Enum), Def::Macro(i, mac_kind) => match mac_kind { MacroKind::Bang => (i, TypeKind::Macro), From e0c75ff40def45bbf39bfed5766a1a8a56f2409f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 12:31:35 +0200 Subject: [PATCH 106/157] rustc: rename item_path to def_path (except the module in ty). --- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/hir/def_id.rs | 2 +- src/librustc/infer/error_reporting/mod.rs | 16 ++--- .../nice_region_error/placeholder_error.rs | 4 +- src/librustc/middle/stability.rs | 4 +- src/librustc/mir/mod.rs | 8 +-- src/librustc/traits/error_reporting.rs | 8 +-- src/librustc/traits/mod.rs | 8 +-- src/librustc/traits/object_safety.rs | 2 +- src/librustc/traits/on_unimplemented.rs | 2 +- src/librustc/traits/project.rs | 2 +- src/librustc/ty/error.rs | 14 ++-- src/librustc/ty/item_path.rs | 68 +++++++++---------- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/query/config.rs | 32 ++++----- src/librustc/util/ppaux.rs | 14 ++-- src/librustc_borrowck/borrowck/mod.rs | 8 +-- src/librustc_codegen_utils/symbol_names.rs | 2 +- .../symbol_names_test.rs | 12 ++-- src/librustc_incremental/assert_dep_graph.rs | 2 +- .../persist/dirty_clean.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 2 +- .../borrow_check/nll/explain_borrow/mod.rs | 2 +- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 4 +- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/rustc_peek.rs | 4 +- src/librustc_mir/util/graphviz.rs | 2 +- src/librustc_mir/util/liveness.rs | 2 +- src/librustc_mir/util/pretty.rs | 8 +-- src/librustc_privacy/lib.rs | 2 +- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_typeck/astconv.rs | 6 +- src/librustc_typeck/check/_match.rs | 4 +- src/librustc_typeck/check/compare_method.rs | 2 +- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 +- src/librustc_typeck/check/method/suggest.rs | 16 ++--- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 4 +- src/librustc_typeck/coherence/builtin.rs | 8 +-- src/librustc_typeck/coherence/mod.rs | 6 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/libsyntax/feature_gate.rs | 2 +- src/test/mir-opt/issue-41697.rs | 2 +- src/test/ui/symbol-names/basic.rs | 2 +- src/test/ui/symbol-names/basic.stderr | 6 +- src/test/ui/symbol-names/impl1.rs | 4 +- src/test/ui/symbol-names/impl1.stderr | 12 ++-- 54 files changed, 174 insertions(+), 174 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 41a4a8031006f..eb75e624d34b2 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -724,7 +724,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId { } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(*self) + tcx.def_path_str(*self) } } @@ -736,7 +736,7 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex { } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(DefId::local(*self)) + tcx.def_path_str(DefId::local(*self)) } } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index ed1c15a73c260..397843fd75afa 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -249,7 +249,7 @@ impl DefId { if self.is_local() && self.index == CRATE_DEF_INDEX { format!("top-level module") } else { - format!("module `{}`", tcx.item_path_str(*self)) + format!("module `{}`", tcx.def_path_str(*self)) } } } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index ebed768fa54ec..2a638853992f3 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -448,10 +448,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Only external crates, if either is from a local // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { - let exp_path = self.tcx.item_path_str(did1); - let found_path = self.tcx.item_path_str(did2); - let exp_abs_path = self.tcx.absolute_item_path_str(did1); - let found_abs_path = self.tcx.absolute_item_path_str(did2); + let exp_path = self.tcx.def_path_str(did1); + let found_path = self.tcx.def_path_str(did2); + let exp_abs_path = self.tcx.absolute_def_path_str(did1); + let found_abs_path = self.tcx.absolute_def_path_str(did2); // We compare strings because DefPath can be different // for imported and non-imported crates if exp_path == found_path || exp_abs_path == found_abs_path { @@ -658,7 +658,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return Some(()); } if let &ty::Adt(def, _) = &ta.sty { - let path_ = self.tcx.item_path_str(def.did.clone()); + let path_ = self.tcx.def_path_str(def.did.clone()); if path_ == other_path { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); return Some(()); @@ -757,8 +757,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1); let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - let path1 = self.tcx.item_path_str(def1.did.clone()); - let path2 = self.tcx.item_path_str(def2.did.clone()); + let path1 = self.tcx.def_path_str(def1.did.clone()); + let path2 = self.tcx.def_path_str(def2.did.clone()); if def1.did == def2.did { // Easy case. Replace same types with `_` to shorten the output and highlight // the differing ones. @@ -1013,7 +1013,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() { let message = format!( "did you mean `{}(/* fields */)`?", - self.tcx.item_path_str(def_id) + self.tcx.def_path_str(def_id) ); diag.span_label(span, message); } diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 506388c268bb1..189ecf53e0e84 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -193,7 +193,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { cause.span(&self.tcx()), &format!( "implementation of `{}` is not general enough", - self.tcx().item_path_str(trait_def_id), + self.tcx().def_path_str(trait_def_id), ), ); @@ -201,7 +201,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { ObligationCauseCode::ItemObligation(def_id) => { err.note(&format!( "Due to a where-clause on `{}`,", - self.tcx().item_path_str(def_id), + self.tcx().def_path_str(def_id), )); } _ => (), diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 1677384059e09..0a2a375e1b2c1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -593,7 +593,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { - let path = self.item_path_str(def_id); + let path = self.def_path_str(def_id); let message = format!("use of deprecated item '{}'", path); lint_deprecated(def_id, id, @@ -620,7 +620,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(id) = id { if let Some(stability) = stability { if let Some(depr) = &stability.rustc_depr { - let path = self.item_path_str(def_id); + let path = self.def_path_str(def_id); if deprecation_in_effect(&depr.since.as_str()) { let message = format!("use of deprecated item '{}'", path); lint_deprecated(def_id, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ec42809ff6569..ea3668cec1544 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2062,7 +2062,7 @@ impl<'tcx> Debug for Place<'tcx> { Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!( fmt, "({}: {:?})", - ty::tls::with(|tcx| tcx.item_path_str(def_id)), + ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty ), Base(PlaceBase::Promoted(ref promoted)) => write!( @@ -2731,7 +2731,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul } // print function definitions if let FnDef(did, _) = ty.sty { - return write!(f, "{}", item_path_str(did)); + return write!(f, "{}", def_path_str(did)); } // print string literals if let ConstValue::Slice(ptr, len) = value { @@ -2756,8 +2756,8 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul write!(f, "{:?}:{}", value, ty) } -fn item_path_str(def_id: DefId) -> String { - ty::tls::with(|tcx| tcx.item_path_str(def_id)) +fn def_path_str(def_id: DefId) -> String { + ty::tls::with(|tcx| tcx.def_path_str(def_id)) } impl<'tcx> graph::DirectedGraph for Mir<'tcx> { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0dd076481c887..6c8fe0875b60c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1285,11 +1285,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!(self.sess, span, E0072, "recursive type `{}` has infinite size", - self.item_path_str(type_def_id)); + self.def_path_str(type_def_id)); err.span_label(span, "recursive type has infinite size"); err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \ at some point to make `{}` representable", - self.item_path_str(type_def_id))); + self.def_path_str(type_def_id))); err } @@ -1299,7 +1299,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { violations: Vec) -> DiagnosticBuilder<'tcx> { - let trait_str = self.item_path_str(trait_def_id); + let trait_str = self.def_path_str(trait_def_id); let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!( self.sess, span, E0038, @@ -1524,7 +1524,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { region, object_ty)); } ObligationCauseCode::ItemObligation(item_def_id) => { - let item_name = tcx.item_path_str(item_def_id); + let item_name = tcx.def_path_str(item_def_id); let msg = format!("required by `{}`", item_name); if let Some(sp) = tcx.hir().span_if_local(item_def_id) { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index df127b934b0b1..78c80b48ee80d 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -650,7 +650,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( ) -> bool { debug!("type_known_to_meet_bound_modulo_regions(ty={:?}, bound={:?})", ty, - infcx.tcx.item_path_str(def_id)); + infcx.tcx.def_path_str(def_id)); let trait_ref = ty::TraitRef { def_id, @@ -665,7 +665,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( let result = infcx.predicate_must_hold_modulo_regions(&obligation); debug!("type_known_to_meet_ty={:?} bound={} => {:?}", - ty, infcx.tcx.item_path_str(def_id), result); + ty, infcx.tcx.def_path_str(def_id), result); if result && (ty.has_infer_types() || ty.has_closure_types()) { // Because of inference "guessing", selection can sometimes claim @@ -692,13 +692,13 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>( Ok(()) => { debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success", ty, - infcx.tcx.item_path_str(def_id)); + infcx.tcx.def_path_str(def_id)); true } Err(e) => { debug!("type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}", ty, - infcx.tcx.item_path_str(def_id), + infcx.tcx.def_path_str(def_id), e); false } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index e7a5138e6893c..1c8ea5c7b9c5b 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { hir::CRATE_HIR_ID, *span, &format!("the trait `{}` cannot be made into an object", - self.item_path_str(trait_def_id)), + self.def_path_str(trait_def_id)), &violation.error_msg()); false } else { diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index c86fd0d52b901..fc0058a1df5ff 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { -> String { let name = tcx.item_name(trait_ref.def_id); - let trait_str = tcx.item_path_str(trait_ref.def_id); + let trait_str = tcx.def_path_str(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id); let generic_map = generics.params.iter().filter_map(|param| { let value = match param.kind { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 197bea1c31189..ab6acc662131b 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1549,7 +1549,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( // should have failed in astconv. bug!("No associated type `{}` for {}", assoc_ty_name, - tcx.item_path_str(impl_def_id)) + tcx.def_path_str(impl_def_id)) } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index f58e5e4fb69f6..342a6204d7fe4 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -125,9 +125,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { Traits(values) => ty::tls::with(|tcx| { report_maybe_different(f, &format!("trait `{}`", - tcx.item_path_str(values.expected)), + tcx.def_path_str(values.expected)), &format!("trait `{}`", - tcx.item_path_str(values.found))) + tcx.def_path_str(values.found))) }), IntMismatch(ref values) => { write!(f, "expected `{:?}`, found `{:?}`", @@ -146,8 +146,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } ProjectionMismatched(ref values) => ty::tls::with(|tcx| { write!(f, "expected {}, found {}", - tcx.item_path_str(values.expected), - tcx.item_path_str(values.found)) + tcx.def_path_str(values.expected), + tcx.def_path_str(values.found)) }), ProjectionBoundsLength(ref values) => { write!(f, "expected {} associated type bindings, found {}", @@ -169,8 +169,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(), ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(), - ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(), - ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(), + ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(), + ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), ty::Array(_, n) => match n { ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) { Some(n) => format!("array of {} elements", n).into(), @@ -199,7 +199,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { if let Some(principal) = inner.principal() { - format!("trait {}", tcx.item_path_str(principal.def_id())).into() + format!("trait {}", tcx.def_path_str(principal.def_id())).into() } else { "trait".into() } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 5a15efc2f1142..9f34f475eff6b 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -16,7 +16,7 @@ thread_local! { static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); } -/// Enforces that item_path_str always returns an absolute path and +/// Enforces that def_path_str always returns an absolute path and /// also enables "type-based" impl paths. This is used when building /// symbols that contain types, where we want the crate name to be /// part of the symbol. @@ -56,7 +56,7 @@ pub fn with_crate_prefix R, R>(f: F) -> R { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - // HACK(eddyb) get rid of `item_path_str` and/or pass `Namespace` explicitly always + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always // (but also some things just print a `DefId` generally so maybe we need this?) fn guess_def_namespace(self, def_id: DefId) -> Namespace { match self.def_key(def_id).disambiguated_data.data { @@ -76,52 +76,52 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a string identifying this `DefId`. This string is /// suitable for user output. It is relative to the current crate /// root, unless with_forced_absolute_paths was used. - pub fn item_path_str_with_substs_and_ns( + pub fn def_path_str_with_substs_and_ns( self, def_id: DefId, substs: Option>, ns: Namespace, ) -> String { - debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); + debug!("def_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); if FORCE_ABSOLUTE.with(|force| force.get()) { - PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, substs, ns) + PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns) } else { - PrintCx::new(self, LocalPathPrinter).print_item_path(def_id, substs, ns) + PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns) } } /// Returns a string identifying this def-id. This string is /// suitable for user output. It is relative to the current crate /// root, unless with_forced_absolute_paths was used. - pub fn item_path_str(self, def_id: DefId) -> String { + pub fn def_path_str(self, def_id: DefId) -> String { let ns = self.guess_def_namespace(def_id); - self.item_path_str_with_substs_and_ns(def_id, None, ns) + self.def_path_str_with_substs_and_ns(def_id, None, ns) } /// Returns a string identifying this local node-id. pub fn node_path_str(self, id: ast::NodeId) -> String { - self.item_path_str(self.hir().local_def_id(id)) + self.def_path_str(self.hir().local_def_id(id)) } /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. - pub fn absolute_item_path_str(self, def_id: DefId) -> String { - debug!("absolute_item_path_str: def_id={:?}", def_id); + pub fn absolute_def_path_str(self, def_id: DefId) -> String { + debug!("absolute_def_path_str: def_id={:?}", def_id); let ns = self.guess_def_namespace(def_id); - PrintCx::new(self, AbsolutePathPrinter).print_item_path(def_id, None, ns) + PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, None, ns) } } impl PrintCx<'a, 'gcx, 'tcx, P> { - pub fn default_print_item_path( + pub fn default_print_def_path( &mut self, def_id: DefId, substs: Option>, ns: Namespace, ) -> P::Path { - debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); + debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); let key = self.tcx.def_key(def_id); - debug!("default_print_item_path: key={:?}", key); + debug!("default_print_def_path: key={:?}", key); match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); @@ -155,13 +155,13 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { data @ DefPathData::ImplTrait | data @ DefPathData::GlobalMetaData(..) => { let parent_did = self.tcx.parent(def_id).unwrap(); - let path = self.print_item_path(parent_did, None, ns); + let path = self.print_def_path(parent_did, None, ns); self.path_append(path, &data.as_interned_str().as_symbol().as_str()) }, DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` let parent_def_id = self.tcx.parent(def_id).unwrap(); - self.print_item_path(parent_def_id, substs, ns) + self.print_def_path(parent_def_id, substs, ns) } } } @@ -202,7 +202,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = self.print_item_path(parent_def_id, None, ns); + let path = self.print_def_path(parent_def_id, None, ns); if let Some(trait_ref) = impl_trait_ref { return self.path_append(path, &format!("", trait_ref, self_ty)); } else { @@ -224,13 +224,13 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { match self_ty.sty { ty::Adt(adt_def, substs) => { // FIXME(eddyb) this should recurse to build the path piecewise. - // self.print_item_path(adt_def.did, Some(substs), ns) + // self.print_def_path(adt_def.did, Some(substs), ns) let mut s = String::new(); crate::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap(); self.path_impl(&s) } - ty::Foreign(did) => self.print_item_path(did, None, ns), + ty::Foreign(did) => self.print_def_path(did, None, ns), ty::Bool | ty::Char | @@ -301,13 +301,13 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { pub trait ItemPathPrinter: Sized { type Path; - fn print_item_path( + fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, ns: Namespace, ) -> Self::Path { - self.default_print_item_path(def_id, substs, ns) + self.default_print_def_path(def_id, substs, ns) } fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -357,12 +357,12 @@ impl LocalPathPrinter { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_item_path( + fn try_print_visible_def_path( self: &mut PrintCx<'_, '_, '_, Self>, def_id: DefId, ns: Namespace, ) -> Option<::Path> { - debug!("try_print_visible_item_path: def_id={:?}", def_id); + debug!("try_print_visible_def_path: def_id={:?}", def_id); // If `def_id` is a direct or injected extern crate, return the // path to the crate followed by the path to the item within the crate. @@ -390,9 +390,9 @@ impl LocalPathPrinter { span, .. }) => { - debug!("try_print_visible_item_path: def_id={:?}", def_id); + debug!("try_print_visible_def_path: def_id={:?}", def_id); let path = if !span.is_dummy() { - self.print_item_path(def_id, None, ns) + self.print_def_path(def_id, None, ns) } else { self.path_crate(cnum) }; @@ -412,7 +412,7 @@ impl LocalPathPrinter { let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); let mut cur_def_key = self.tcx.def_key(def_id); - debug!("try_print_visible_item_path: cur_def_key={:?}", cur_def_key); + debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); // For a UnitStruct or TupleStruct we want the name of its parent rather than . if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { @@ -425,12 +425,12 @@ impl LocalPathPrinter { } let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = self.try_print_visible_item_path(visible_parent, ns)?; + let path = self.try_print_visible_def_path(visible_parent, ns)?; let actual_parent = self.tcx.parent(def_id); let data = cur_def_key.disambiguated_data.data; debug!( - "try_print_visible_item_path: data={:?} visible_parent={:?} actual_parent={:?}", + "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", data, visible_parent, actual_parent, ); @@ -485,7 +485,7 @@ impl LocalPathPrinter { }) }, }; - debug!("try_print_visible_item_path: symbol={:?}", symbol); + debug!("try_print_visible_def_path: symbol={:?}", symbol); Some(self.path_append(path, &symbol)) } } @@ -493,14 +493,14 @@ impl LocalPathPrinter { impl ItemPathPrinter for LocalPathPrinter { type Path = String; - fn print_item_path( + fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, ns: Namespace, ) -> Self::Path { - self.try_print_visible_item_path(def_id, ns) - .unwrap_or_else(|| self.default_print_item_path(def_id, substs, ns)) + self.try_print_visible_def_path(def_id, ns) + .unwrap_or_else(|| self.default_print_def_path(def_id, substs, ns)) } fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -522,7 +522,7 @@ impl ItemPathPrinter for LocalPathPrinter { // only occur very early in the compiler pipeline. // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); - let path = self.print_item_path(parent_def_id, None, ns); + let path = self.print_def_path(parent_def_id, None, ns); let span = self.tcx.def_span(impl_def_id); return self.path_append(path, &format!("", span)); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ddb3911daeb5d..4f933bf0d538d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2056,7 +2056,7 @@ impl ReprOptions { } // This is here instead of layout because the choice must make it into metadata. - if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) { + if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) { flags.insert(ReprFlags::IS_LINEAR); } ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 6488c0db42bc5..395b288df141e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -71,7 +71,7 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> { impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M { default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { if !tcx.sess.verbose() { - format!("processing `{}`", tcx.item_path_str(def_id)).into() + format!("processing `{}`", tcx.def_path_str(def_id)).into() } else { let name = unsafe { ::std::intrinsics::type_name::() }; format!("processing {:?} with query `{}`", def_id, name).into() @@ -301,7 +301,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("computing the supertraits of `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } @@ -322,7 +322,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("coherence checking all impls of trait `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } @@ -359,7 +359,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { format!("generating MIR shim for `{}`", - tcx.item_path_str(def.def_id())).into() + tcx.def_path_str(def.def_id())).into() } } @@ -394,7 +394,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { ) -> Cow<'static, str> { format!( "const-evaluating + checking `{}`", - tcx.item_path_str(key.value.instance.def.def_id()), + tcx.def_path_str(key.value.instance.def.def_id()), ).into() } @@ -415,7 +415,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> Cow<'static, str> { - format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into() + format!("const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id())).into() } #[inline] @@ -513,7 +513,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("const checking if rvalue is promotable to static `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } #[inline] @@ -532,21 +532,21 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking which parts of `{}` are promotable to static", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { format!("checking if item is mir available: `{}`", - tcx.item_path_str(def_id)).into() + tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> { - format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id())) + format!("checking if `{}` fulfills its obligations", tcx.def_path_str(key.1.def_id())) .into() } @@ -565,19 +565,19 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("trait impls of `{}`", tcx.item_path_str(def_id)).into() + format!("trait impls of `{}`", tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into() + format!("determine object safety of trait `{}`", tcx.def_path_str(def_id)).into() } } impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> { - format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into() + format!("checking if item is const fn: `{}`", tcx.def_path_str(def_id)).into() } } @@ -883,7 +883,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> { - format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into() + format!("finding all methods for trait {}", tcx.def_path_str(key.def_id())).into() } } @@ -927,7 +927,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> { - format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into() + format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into() } } @@ -945,7 +945,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> { impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> { - format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into() + format!("estimating size for `{}`", tcx.def_path_str(def.def_id())).into() } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 092255129f4ee..cf92ab2f2ff47 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -320,7 +320,7 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { // FIXME(eddyb) recurse through printing a path via `self`, instead // instead of using the `tcx` method that produces a `String`. print!(self, write("{}", - self.tcx.item_path_str_with_substs_and_ns(def_id, Some(substs), ns)))?; + self.tcx.def_path_str_with_substs_and_ns(def_id, Some(substs), ns)))?; // For impls, the above call already prints relevant generics args. if let DefPathData::Impl = key.disambiguated_data.data { @@ -515,7 +515,7 @@ define_print! { if let Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - print!(cx, write("{}", cx.tcx.item_path_str(principal.def_id)))?; + print!(cx, write("{}", cx.tcx.def_path_str(principal.def_id)))?; cx.fn_sig(args, false, proj.ty)?; resugared_principal = true; } @@ -538,7 +538,7 @@ define_print! { // Builtin bounds. let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - cx.tcx.item_path_str(did) + cx.tcx.def_path_str(did) }).collect(); // The auto traits come ordered by `DefPathHash`. While @@ -582,7 +582,7 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |cx| { - print!(cx, write("{}", cx.tcx.item_path_str(self.def_id))) + print!(cx, write("{}", cx.tcx.def_path_str(self.def_id))) }) } } @@ -590,7 +590,7 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |cx| { - print!(cx, write("{}", cx.tcx.item_path_str(self.did))) + print!(cx, write("{}", cx.tcx.def_path_str(self.did))) }) } } @@ -1513,11 +1513,11 @@ define_print! { ty::Predicate::WellFormed(ty) => print!(cx, print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { print!(cx, write("the trait `{}` is object-safe", - cx.tcx.item_path_str(trait_def_id))) + cx.tcx.def_path_str(trait_def_id))) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { print!(cx, write("the closure `{}` implements the trait `{}`", - cx.tcx.item_path_str(closure_def_id), kind)) + cx.tcx.def_path_str(closure_def_id), kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { print!(cx, write("the constant `"))?; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index da065f9e05d9e..01bfe5d5af706 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1406,7 +1406,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { out.push('('); self.append_loan_path_to_string(&lp_base, out); out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.item_path_str(variant_def_id)); + out.push_str(&self.tcx.def_path_str(variant_def_id)); out.push(')'); } @@ -1443,7 +1443,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { out.push('('); self.append_autoderefd_loan_path_to_string(&lp_base, out); out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&self.tcx.item_path_str(variant_def_id)); + out.push_str(&self.tcx.def_path_str(variant_def_id)); out.push(')'); } @@ -1523,7 +1523,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; @@ -1558,7 +1558,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.is_local() { - ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) + ty::tls::with(|tcx| tcx.def_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index a7771f3da18ee..1417cbf126558 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -227,7 +227,7 @@ fn get_symbol_hash<'a, 'tcx>( fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { item_path::with_forced_absolute_paths(|| { PrintCx::new(tcx, SymbolPathPrinter) - .print_item_path(def_id, None, Namespace::ValueNS) + .print_def_path(def_id, None, Namespace::ValueNS) .into_interned() }) } diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index c495268154664..6a2b6f1321b88 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -1,7 +1,7 @@ //! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and +//! either a `rustc_symbol_name` or `rustc_def_path` attribute and //! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates +//! def-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. use rustc::hir; @@ -10,7 +10,7 @@ use rustc::ty::TyCtxt; use rustc_mir::monomorphize::Instance; const SYMBOL_NAME: &'static str = "rustc_symbol_name"; -const ITEM_PATH: &'static str = "rustc_item_path"; +const DEF_PATH: &'static str = "rustc_def_path"; pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // if the `rustc_attrs` feature is not enabled, then the @@ -41,9 +41,9 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { let instance = Instance::mono(tcx, def_id); let name = self.tcx.symbol_name(instance); tcx.sess.span_err(attr.span, &format!("symbol-name({})", name)); - } else if attr.check_name(ITEM_PATH) { - let path = tcx.item_path_str(def_id); - tcx.sess.span_err(attr.span, &format!("item-path({})", path)); + } else if attr.check_name(DEF_PATH) { + let path = tcx.def_path_str(def_id); + tcx.sess.span_err(attr.span, &format!("def-path({})", path)); } // (*) The formatting of `tag({})` is chosen so that tests can elect diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 1f69d617c83b7..9fe9a60b9aaa9 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -206,7 +206,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.sess.span_err( target_span, &format!("no path from `{}` to `{}`", - tcx.item_path_str(source_def_id), + tcx.def_path_str(source_def_id), target_pass)); } else { tcx.sess.span_err( diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 2794b6c556ff2..633e61a0034ab 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -463,7 +463,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { if let Some(def_id) = dep_node.extract_def_id(self.tcx) { format!("{:?}({})", dep_node.kind, - self.tcx.item_path_str(def_id)) + self.tcx.def_path_str(def_id)) } else { format!("{:?}({:?})", dep_node.kind, dep_node.hash) } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 86b8b276eafe5..7d61547527f76 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -182,7 +182,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { let msg = format!("unused {}`{}`{} that must be used", - descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path); + descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 62cfa184430be..0f0811b562ea3 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -68,7 +68,7 @@ pub fn provide(providers: &mut Providers<'_>) { fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> { let input_mir = tcx.mir_validated(def_id); - debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id)); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id)); let mut return_early; diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 17f8c23f4fddc..dfa5af444d37e 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -93,7 +93,7 @@ impl BorrowExplanation { // simplify output by reporting just the ADT name. ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => ( "`Drop` code", - format!("type `{}`", tcx.item_path_str(adt.did)), + format!("type `{}`", tcx.def_path_str(adt.did)), ), // Otherwise, just report the whole type (and use diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 365cb508b0925..e6005142b85ef 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -142,7 +142,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack); - let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id())); + let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id())); let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p)); trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom); assert!(mir.arg_count == 0); diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 41babc1ad12ef..49967df08891b 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -319,7 +319,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa if edef.is_enum() && edef.variants.iter().any(|variant| { variant.ident == ident && variant.ctor_kind == CtorKind::Const }) { - let ty_path = cx.tcx.item_path_str(edef.did); + let ty_path = cx.tcx.def_path_str(edef.did); let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, "pattern binding `{}` is named the same as one \ of the variants of the type `{}`", diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index f1a3c682b5384..ad7b45d89453a 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -969,8 +969,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => { let msg = format!("to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - self.tcx.item_path_str(adt_def.did), - self.tcx.item_path_str(adt_def.did)); + self.tcx.def_path_str(adt_def.did), + self.tcx.def_path_str(adt_def.did)); self.tcx.sess.span_err(span, &msg); PatternKind::Wild } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 8a32c3b636c71..d92ab0c517956 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(NoMirFor(self.tcx.item_path_str(def_id))) + err!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 97d566e586e86..001a61959c2dd 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { if !self.span.allows_unstable(&feature.as_str()) { let mut err = self.tcx.sess.struct_span_err(self.span, &format!("`{}` is not yet stable as a const fn", - self.tcx.item_path_str(def_id))); + self.tcx.def_path_str(def_id))); if nightly_options::is_nightly_build() { help!(&mut err, "add `#![feature({})]` to the \ diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index f078316b97ce8..f9f8abbe6c065 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -29,10 +29,10 @@ impl MirPass for SanityCheck { let def_id = src.def_id(); let id = tcx.hir().as_local_hir_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir") { - debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); + debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); return; } else { - debug!("running rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); + debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); } let attributes = tcx.get_attrs(def_id); diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 41e16684b8ac5..69a2adcfce026 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -127,7 +127,7 @@ fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &Mir<'_>, w: &mut W) -> io::Result<()> { - write!(w, " label=( } let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result); } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c3fbee3a2a6e5..12d4e90c7c002 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -80,7 +80,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); dump_matched_mir_node( tcx, @@ -105,7 +105,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( }; let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(source.def_id()) + tcx.def_path_str(source.def_id()) }); filters.split('|').any(|or_filter| { or_filter.split('&').all(|and_filter| { @@ -115,7 +115,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( } // #41697 -- we use `with_forced_impl_filename_line()` because -// `item_path_str()` would otherwise trigger `type_of`, and this can +// `def_path_str()` would otherwise trigger `type_of`, and this can // run while we are already attempting to evaluate `type_of`. fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( @@ -614,7 +614,7 @@ fn write_mir_sig( item_path::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere - write!(w, "{}", tcx.item_path_str(src.def_id())) + write!(w, " {}", tcx.def_path_str(src.def_id())) })?; if src.promoted.is_none() && is_function { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index c7e63a83b1561..5065c1de97bee 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -816,7 +816,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> { let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1; if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private", - field.ident, def.variant_descr(), self.tcx.item_path_str(def.did)) + field.ident, def.variant_descr(), self.tcx.def_path_str(def.did)) .span_label(span, format!("field `{}` is private", field.ident)) .emit(); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 2aa44a9242ef1..97b9db34ed525 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -411,7 +411,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if let Some(def_id) = trait_id { // A method in a trait impl. qualname.push_str(" as "); - qualname.push_str(&self.tcx.item_path_str(def_id)); + qualname.push_str(&self.tcx.def_path_str(def_id)); self.tcx .associated_items(def_id) .find(|item| item.ident.name == ident.name) @@ -451,7 +451,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ( - format!("::{}", self.tcx.item_path_str(def_id)), + format!("::{}", self.tcx.def_path_str(def_id)), Some(def_id), None, docs, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4e952f972e459..9ca75566b4280 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -922,7 +922,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { "the value of the associated type `{}` (from the trait `{}`) \ is already specified", binding.item_name, - tcx.item_path_str(assoc_ty.container.id())) + tcx.def_path_str(assoc_ty.container.id())) .span_label(binding.span, "re-bound here") .span_label(*prev_span, format!("`{}` bound here first", binding.item_name)) .emit(); @@ -1071,7 +1071,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { format!( "`{}` (from the trait `{}`)", assoc_item.ident, - tcx.item_path_str(trait_def_id), + tcx.def_path_str(trait_def_id), ) }).collect::>().join(", "); let mut err = struct_span_err!( @@ -1459,7 +1459,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let self_ty = if let Some(ty) = opt_self_ty { ty } else { - let path_str = tcx.item_path_str(trait_def_id); + let path_str = tcx.def_path_str(trait_def_id); self.report_ambiguous_associated_type(span, "Type", &path_str, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 342a214e0cc22..c6b66393dd2f1 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -1001,13 +1001,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); E0026, "{} `{}` does not have {}", kind_name, - tcx.item_path_str(variant.did), + tcx.def_path_str(variant.did), field_names); if let Some((span, ident)) = inexistent_fields.last() { err.span_label(*span, format!("{} `{}` does not have {} field{}", kind_name, - tcx.item_path_str(variant.did), + tcx.def_path_str(variant.did), t, plural)); if plural == "" { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index f79bf4e999d54..e6e5c46c473d5 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -719,7 +719,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait `{}` has {}", trait_m.ident, potentially_plural_count(impl_number_args, "parameter"), - tcx.item_path_str(trait_m.def_id), + tcx.def_path_str(trait_m.def_id), trait_number_args); if let Some(trait_span) = trait_span { err.span_label(trait_span, format!("trait requires {}", diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 32ca854b27744..3a7308d09172e 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -130,7 +130,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let sole_field = &variant.fields[0]; let sole_field_ty = sole_field.ty(self.tcx, substs); if self.can_coerce(expr_ty, sole_field_ty) { - let variant_path = self.tcx.item_path_str(variant.did); + let variant_path = self.tcx.def_path_str(variant.did); // FIXME #56861: DRYer prelude filtering Some(variant_path.trim_start_matches("std::prelude::v1::").to_string()) } else { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index efae870c3c3a9..1f0ab3abb2836 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1195,7 +1195,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // `report_method_error()`. diag.help(&format!( "call with fully qualified syntax `{}(...)` to keep using the current method", - self.tcx.item_path_str(stable_pick.item.def_id), + self.tcx.def_path_str(stable_pick.item.def_id), )); if nightly_options::is_nightly_build() { @@ -1203,7 +1203,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { diag.help(&format!( "add #![feature({})] to the crate attributes to enable `{}`", feature, - self.tcx.item_path_str(candidate.item.def_id), + self.tcx.def_path_str(candidate.item.def_id), )); } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4bf6471a6293c..f784a720b19c4 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => String::new(), Some(trait_ref) => { format!(" of the trait `{}`", - self.tcx.item_path_str(trait_ref.def_id)) + self.tcx.def_path_str(trait_ref.def_id)) } }; @@ -135,16 +135,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { item_span, "candidate #{} is defined in the trait `{}`", idx + 1, - self.tcx.item_path_str(trait_did)); + self.tcx.def_path_str(trait_did)); } else { span_note!(err, item_span, "the candidate is defined in the trait `{}`", - self.tcx.item_path_str(trait_did)); + self.tcx.def_path_str(trait_did)); } err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \ instead", - self.tcx.item_path_str(trait_did), + self.tcx.def_path_str(trait_did), item_name, if rcvr_ty.is_region_ptr() && args.is_some() { if rcvr_ty.is_mutable_pointer() { @@ -516,7 +516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; format!( "use {};\n{}", - with_crate_prefix(|| self.tcx.item_path_str(*did)), + with_crate_prefix(|| self.tcx.def_path_str(*did)), additional_newline ) }); @@ -530,14 +530,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &format!( "\ncandidate #{}: `use {};`", i + 1, - with_crate_prefix(|| self.tcx.item_path_str(*trait_did)) + with_crate_prefix(|| self.tcx.def_path_str(*trait_did)) ) ); } else { msg.push_str( &format!( "\n`use {};`", - with_crate_prefix(|| self.tcx.item_path_str(*trait_did)) + with_crate_prefix(|| self.tcx.def_path_str(*trait_did)) ) ); } @@ -638,7 +638,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for (i, trait_info) in candidates.iter().enumerate() { msg.push_str(&format!("\ncandidate #{}: `{}`", i + 1, - self.tcx.item_path_str(trait_info.def_id))); + self.tcx.def_path_str(trait_info.def_id))); } err.note(&msg[..]); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c40bdae0762a9..1383bf28113d8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1328,7 +1328,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite debug!( "check_item_type(it.hir_id={}, it.name={})", it.hir_id, - tcx.item_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id)) + tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id)) ); let _indenter = indenter(); match it.node { @@ -3534,7 +3534,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { autoderef.unambiguous_final_ty(self); if let Some((did, field_ty)) = private_candidate { - let struct_path = self.tcx().item_path_str(did); + let struct_path = self.tcx().def_path_str(did); let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616, "field `{}` of struct `{}` is private", field, struct_path); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 92c44e24998e5..1f7e05de18bcf 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -68,7 +68,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def debug!("check_item_well_formed(it.hir_id={:?}, it.name={})", item.hir_id, - tcx.item_path_str(def_id)); + tcx.def_path_str(def_id)); match item.node { // Right now we check that every default trait implementation @@ -976,7 +976,7 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(def_id) = suggested_marker_id { err.help(&format!("consider removing `{}` or using a marker such as `{}`", param_name, - tcx.item_path_str(def_id))); + tcx.def_path_str(def_id))); } err.emit(); } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 5d86bc5409532..a2b01e3843ff2 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -198,8 +198,8 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>( if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = tcx.item_path_str(def_a.did); - let target_path = tcx.item_path_str(def_b.did); + let source_path = tcx.def_path_str(def_a.did); + let target_path = tcx.def_path_str(def_b.did); create_err( &format!( @@ -388,8 +388,8 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>, (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = gcx.item_path_str(def_a.did); - let target_path = gcx.item_path_str(def_b.did); + let source_path = gcx.def_path_str(def_a.did); + let target_path = gcx.def_path_str(def_b.did); span_err!(gcx.sess, span, E0377, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 39a2f5d37bd7a..a5452b4db2a20 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -28,7 +28,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { debug!("(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, - tcx.item_path_str(impl_def_id)); + tcx.def_path_str(impl_def_id)); // Skip impls where one of the self type is an error type. // This occurs with e.g., resolve failures (#30589). @@ -204,10 +204,10 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI E0371, "the object type `{}` automatically implements the trait `{}`", trait_ref.self_ty(), - tcx.item_path_str(trait_def_id)) + tcx.def_path_str(trait_def_id)) .span_label(sp, format!("`{}` automatically implements trait `{}`", trait_ref.self_ty(), - tcx.item_path_str(trait_def_id))) + tcx.def_path_str(trait_def_id))) .emit(); } } diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index c875b856f3a4f..7e1c38e051542 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -121,7 +121,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { format!("cross-crate traits with a default impl, like `{}`, \ can only be implemented for a struct/enum type \ defined in the current crate", - self.tcx.item_path_str(trait_def_id)), + self.tcx.def_path_str(trait_def_id)), "can't implement cross-crate trait for type in another crate" )) } @@ -129,7 +129,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { _ => { Some((format!("cross-crate traits with a default impl, like `{}`, can \ only be implemented for a struct/enum type, not `{}`", - self.tcx.item_path_str(trait_def_id), + self.tcx.def_path_str(trait_def_id), self_ty), "can't implement cross-crate trait with a default impl for \ non-struct/enum type")) diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 49d11150689a9..c18f9fd102f10 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn build_constraints_for_item(&mut self, def_id: DefId) { let tcx = self.tcx(); - debug!("build_constraints_for_item({})", tcx.item_path_str(def_id)); + debug!("build_constraints_for_item({})", tcx.def_path_str(def_id)); // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(def_id).count() == 0 { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e2e2d552ff122..08d165b82b1db 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4250,7 +4250,7 @@ where F: Fn(DefId) -> Def { } let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_item_path(def_id, None, Namespace::TypeNS); + .print_def_path(def_id, None, Namespace::TypeNS); hir::Path { span: DUMMY_SP, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 279e2089f5d71..b2982629fe6b2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1042,7 +1042,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), - ("rustc_item_path", Whitelisted, template!(Word), Gated(Stability::Unstable, + ("rustc_def_path", Whitelisted, template!(Word), Gated(Stability::Unstable, "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index 9db25b15f6835..5a461d6148254 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -1,7 +1,7 @@ // Regression test for #41697. Using dump-mir was triggering // artificial cycles: during type-checking, we had to get the MIR for // the constant expressions in `[u8; 2]`, which in turn would trigger -// an attempt to get the item-path, which in turn would request the +// an attempt to get the def-path, which in turn would request the // types of the impl, which would trigger a cycle. We suppressed this // cycle now by forcing mir-dump to avoid asking for types of an impl. diff --git a/src/test/ui/symbol-names/basic.rs b/src/test/ui/symbol-names/basic.rs index 2a051a5e144da..086b903b973b0 100644 --- a/src/test/ui/symbol-names/basic.rs +++ b/src/test/ui/symbol-names/basic.rs @@ -1,6 +1,6 @@ #![feature(rustc_attrs)] #[rustc_symbol_name] //~ ERROR _ZN5basic4main -#[rustc_item_path] //~ ERROR item-path(main) +#[rustc_def_path] //~ ERROR def-path(main) fn main() { } diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr index e23a326d5f889..6ddd93d632e15 100644 --- a/src/test/ui/symbol-names/basic.stderr +++ b/src/test/ui/symbol-names/basic.stderr @@ -4,11 +4,11 @@ error: symbol-name(_ZN5basic4main17h08bcaf310214ed52E) LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(main) +error: def-path(main) --> $DIR/basic.rs:4:1 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 69cd49e39512e..992527017fb7c 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -6,7 +6,7 @@ mod foo { impl Foo { #[rustc_symbol_name] //~ ERROR _ZN15impl1..foo..Foo3bar - #[rustc_item_path] //~ ERROR item-path(foo::Foo::bar) + #[rustc_def_path] //~ ERROR def-path(foo::Foo::bar) fn bar() { } } } @@ -16,7 +16,7 @@ mod bar { impl Foo { #[rustc_symbol_name] //~ ERROR _ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz - #[rustc_item_path] //~ ERROR item-path(bar::::baz) + #[rustc_def_path] //~ ERROR def-path(bar::::baz) fn baz() { } } } diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr index 4041eb6b0ba4a..d225c53e4927a 100644 --- a/src/test/ui/symbol-names/impl1.stderr +++ b/src/test/ui/symbol-names/impl1.stderr @@ -4,11 +4,11 @@ error: symbol-name(_ZN15impl1..foo..Foo3bar17hc487d6ec13fe9124E) LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(foo::Foo::bar) +error: def-path(foo::Foo::bar) --> $DIR/impl1.rs:9:9 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h38577281258e1527E) --> $DIR/impl1.rs:18:9 @@ -16,11 +16,11 @@ error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h385772 LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: item-path(bar::::baz) +error: def-path(bar::::baz) --> $DIR/impl1.rs:19:9 | -LL | #[rustc_item_path] - | ^^^^^^^^^^^^^^^^^^ +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors From 9f8aaa04e02c74209e3ea355d8888cbc59a8fb64 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 13:25:31 +0200 Subject: [PATCH 107/157] rustc: move the contents of ty::item_path to ty::print. --- src/librustc/ty/item_path.rs | 560 ------------------ src/librustc/ty/mod.rs | 1 - src/librustc/ty/print.rs | 560 +++++++++++++++++- src/librustc/ty/query/plumbing.rs | 5 +- src/librustc_codegen_utils/symbol_names.rs | 7 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- src/librustc_mir/util/liveness.rs | 4 +- src/librustc_mir/util/pretty.rs | 7 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustdoc/clean/mod.rs | 5 +- 10 files changed, 573 insertions(+), 580 deletions(-) delete mode 100644 src/librustc/ty/item_path.rs diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs deleted file mode 100644 index 9f34f475eff6b..0000000000000 --- a/src/librustc/ty/item_path.rs +++ /dev/null @@ -1,560 +0,0 @@ -use crate::hir::def::Namespace; -use crate::hir::map::DefPathData; -use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt}; -use crate::ty::print::PrintCx; -use crate::ty::subst::{Subst, SubstsRef}; -use crate::middle::cstore::{ExternCrate, ExternCrateSource}; -use syntax::ast; -use syntax::symbol::{keywords, Symbol}; - -use std::cell::Cell; - -thread_local! { - static FORCE_ABSOLUTE: Cell = Cell::new(false); - static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); - static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); -} - -/// Enforces that def_path_str always returns an absolute path and -/// also enables "type-based" impl paths. This is used when building -/// symbols that contain types, where we want the crate name to be -/// part of the symbol. -pub fn with_forced_absolute_paths R, R>(f: F) -> R { - FORCE_ABSOLUTE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - -/// Force us to name impls with just the filename/line number. We -/// normally try to use types. But at some points, notably while printing -/// cycle errors, this can result in extra or suboptimal error output, -/// so this variable disables that check. -pub fn with_forced_impl_filename_line R, R>(f: F) -> R { - FORCE_IMPL_FILENAME_LINE.with(|force| { - let old = force.get(); - force.set(true); - let result = f(); - force.set(old); - result - }) -} - -/// Adds the `crate::` prefix to paths where appropriate. -pub fn with_crate_prefix R, R>(f: F) -> R { - SHOULD_PREFIX_WITH_CRATE.with(|flag| { - let old = flag.get(); - flag.set(true); - let result = f(); - flag.set(old); - result - }) -} - -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always - // (but also some things just print a `DefId` generally so maybe we need this?) - fn guess_def_namespace(self, def_id: DefId) -> Namespace { - match self.def_key(def_id).disambiguated_data.data { - DefPathData::ValueNs(..) | - DefPathData::EnumVariant(..) | - DefPathData::Field(..) | - DefPathData::AnonConst | - DefPathData::ClosureExpr | - DefPathData::StructCtor => Namespace::ValueNS, - - DefPathData::MacroDef(..) => Namespace::MacroNS, - - _ => Namespace::TypeNS, - } - } - - /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. It is relative to the current crate - /// root, unless with_forced_absolute_paths was used. - pub fn def_path_str_with_substs_and_ns( - self, - def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> String { - debug!("def_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); - if FORCE_ABSOLUTE.with(|force| force.get()) { - PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns) - } else { - PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns) - } - } - - /// Returns a string identifying this def-id. This string is - /// suitable for user output. It is relative to the current crate - /// root, unless with_forced_absolute_paths was used. - pub fn def_path_str(self, def_id: DefId) -> String { - let ns = self.guess_def_namespace(def_id); - self.def_path_str_with_substs_and_ns(def_id, None, ns) - } - - /// Returns a string identifying this local node-id. - pub fn node_path_str(self, id: ast::NodeId) -> String { - self.def_path_str(self.hir().local_def_id(id)) - } - - /// Returns a string identifying this def-id. This string is - /// suitable for user output. It always begins with a crate identifier. - pub fn absolute_def_path_str(self, def_id: DefId) -> String { - debug!("absolute_def_path_str: def_id={:?}", def_id); - let ns = self.guess_def_namespace(def_id); - PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, None, ns) - } -} - -impl PrintCx<'a, 'gcx, 'tcx, P> { - pub fn default_print_def_path( - &mut self, - def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> P::Path { - debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); - let key = self.tcx.def_key(def_id); - debug!("default_print_def_path: key={:?}", key); - match key.disambiguated_data.data { - DefPathData::CrateRoot => { - assert!(key.parent.is_none()); - self.path_crate(def_id.krate) - } - - DefPathData::Impl => { - self.print_impl_path(def_id, substs, ns) - } - - // Unclear if there is any value in distinguishing these. - // Probably eventually (and maybe we would even want - // finer-grained distinctions, e.g., between enum/struct). - data @ DefPathData::Misc | - data @ DefPathData::TypeNs(..) | - data @ DefPathData::Trait(..) | - data @ DefPathData::TraitAlias(..) | - data @ DefPathData::AssocTypeInTrait(..) | - data @ DefPathData::AssocTypeInImpl(..) | - data @ DefPathData::AssocExistentialInImpl(..) | - data @ DefPathData::ValueNs(..) | - data @ DefPathData::Module(..) | - data @ DefPathData::TypeParam(..) | - data @ DefPathData::LifetimeParam(..) | - data @ DefPathData::ConstParam(..) | - data @ DefPathData::EnumVariant(..) | - data @ DefPathData::Field(..) | - data @ DefPathData::AnonConst | - data @ DefPathData::MacroDef(..) | - data @ DefPathData::ClosureExpr | - data @ DefPathData::ImplTrait | - data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.tcx.parent(def_id).unwrap(); - let path = self.print_def_path(parent_did, None, ns); - self.path_append(path, &data.as_interned_str().as_symbol().as_str()) - }, - - DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` - let parent_def_id = self.tcx.parent(def_id).unwrap(); - self.print_def_path(parent_def_id, substs, ns) - } - } - } - - fn default_print_impl_path( - &mut self, - impl_def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> P::Path { - debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); - - // Decide whether to print the parent path for the impl. - // Logically, since impls are global, it's never needed, but - // users may find it useful. Currently, we omit the parent if - // the impl is either in the same module as the self-type or - // as the trait. - let mut self_ty = self.tcx.type_of(impl_def_id); - if let Some(substs) = substs { - self_ty = self_ty.subst(self.tcx, substs); - } - let in_self_mod = match characteristic_def_id_of_type(self_ty) { - None => false, - Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), - }; - - let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); - if let Some(substs) = substs { - impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); - } - let in_trait_mod = match impl_trait_ref { - None => false, - Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), - }; - - if !in_self_mod && !in_trait_mod { - // If the impl is not co-located with either self-type or - // trait-type, then fallback to a format that identifies - // the module more clearly. - let path = self.print_def_path(parent_def_id, None, ns); - if let Some(trait_ref) = impl_trait_ref { - return self.path_append(path, &format!("", trait_ref, self_ty)); - } else { - return self.path_append(path, &format!("", self_ty)); - } - } - - // Otherwise, try to give a good form that would be valid language - // syntax. Preferably using associated item notation. - - if let Some(trait_ref) = impl_trait_ref { - // Trait impls. - return self.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); - } - - // Inherent impls. Try to print `Foo::bar` for an inherent - // impl on `Foo`, but fallback to `::bar` if self-type is - // anything other than a simple path. - match self_ty.sty { - ty::Adt(adt_def, substs) => { - // FIXME(eddyb) this should recurse to build the path piecewise. - // self.print_def_path(adt_def.did, Some(substs), ns) - let mut s = String::new(); - crate::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap(); - self.path_impl(&s) - } - - ty::Foreign(did) => self.print_def_path(did, None, ns), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::Str => { - self.path_impl(&self_ty.to_string()) - } - - _ => { - self.path_impl(&format!("<{}>", self_ty)) - } - } - } -} - -/// As a heuristic, when we see an impl, if we see that the -/// 'self type' is a type defined in the same module as the impl, -/// we can omit including the path to the impl itself. This -/// function tries to find a "characteristic `DefId`" for a -/// type. It's just a heuristic so it makes some questionable -/// decisions and we may want to adjust it later. -pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Adt(adt_def, _) => Some(adt_def.did), - - ty::Dynamic(data, ..) => data.principal_def_id(), - - ty::Array(subty, _) | - ty::Slice(subty) => characteristic_def_id_of_type(subty), - - ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty), - - ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty), - - ty::Tuple(ref tys) => tys.iter() - .filter_map(|ty| characteristic_def_id_of_type(ty)) - .next(), - - ty::FnDef(def_id, _) | - ty::Closure(def_id, _) | - ty::Generator(def_id, _, _) | - ty::Foreign(def_id) => Some(def_id), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Str | - ty::FnPtr(_) | - ty::Projection(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Param(_) | - ty::Opaque(..) | - ty::Infer(_) | - ty::Bound(..) | - ty::Error | - ty::GeneratorWitness(..) | - ty::Never | - ty::Float(_) => None, - } -} - -/// Unifying Trait for different kinds of item paths we might -/// construct. The basic interface is that components get appended. -pub trait ItemPathPrinter: Sized { - type Path; - - fn print_def_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> Self::Path { - self.default_print_def_path(def_id, substs, ns) - } - fn print_impl_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> Self::Path { - self.default_print_impl_path(impl_def_id, substs, ns) - } - - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - path: Self::Path, - text: &str, - ) -> Self::Path; -} - -struct AbsolutePathPrinter; - -impl ItemPathPrinter for AbsolutePathPrinter { - type Path = String; - - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - self.tcx.original_crate_name(cnum).to_string() - } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - text.to_string() - } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, - text: &str, - ) -> Self::Path { - if !path.is_empty() { - path.push_str("::"); - } - path.push_str(text); - path - } -} - -struct LocalPathPrinter; - -impl LocalPathPrinter { - /// If possible, this returns a global path resolving to `def_id` that is visible - /// from at least one local module and returns true. If the crate defining `def_id` is - /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path( - self: &mut PrintCx<'_, '_, '_, Self>, - def_id: DefId, - ns: Namespace, - ) -> Option<::Path> { - debug!("try_print_visible_def_path: def_id={:?}", def_id); - - // If `def_id` is a direct or injected extern crate, return the - // path to the crate followed by the path to the item within the crate. - if def_id.index == CRATE_DEF_INDEX { - let cnum = def_id.krate; - - if cnum == LOCAL_CRATE { - return Some(self.path_crate(cnum)); - } - - // In local mode, when we encounter a crate other than - // LOCAL_CRATE, execution proceeds in one of two ways: - // - // 1. for a direct dependency, where user added an - // `extern crate` manually, we put the `extern - // crate` as the parent. So you wind up with - // something relative to the current crate. - // 2. for an extern inferred from a path or an indirect crate, - // where there is no explicit `extern crate`, we just prepend - // the crate name. - match *self.tcx.extern_crate(def_id) { - Some(ExternCrate { - src: ExternCrateSource::Extern(def_id), - direct: true, - span, - .. - }) => { - debug!("try_print_visible_def_path: def_id={:?}", def_id); - let path = if !span.is_dummy() { - self.print_def_path(def_id, None, ns) - } else { - self.path_crate(cnum) - }; - return Some(path); - } - None => { - return Some(self.path_crate(cnum)); - } - _ => {}, - } - } - - if def_id.is_local() { - return None; - } - - let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); - - let mut cur_def_key = self.tcx.def_key(def_id); - debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); - - // For a UnitStruct or TupleStruct we want the name of its parent rather than . - if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { - let parent = DefId { - krate: def_id.krate, - index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), - }; - - cur_def_key = self.tcx.def_key(parent); - } - - let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = self.try_print_visible_def_path(visible_parent, ns)?; - let actual_parent = self.tcx.parent(def_id); - - let data = cur_def_key.disambiguated_data.data; - debug!( - "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", - data, visible_parent, actual_parent, - ); - - let symbol = match data { - // In order to output a path that could actually be imported (valid and visible), - // we need to handle re-exports correctly. - // - // For example, take `std::os::unix::process::CommandExt`, this trait is actually - // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). - // - // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is - // private so the "true" path to `CommandExt` isn't accessible. - // - // In this case, the `visible_parent_map` will look something like this: - // - // (child) -> (parent) - // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` - // `std::sys::unix::ext::process` -> `std::sys::unix::ext` - // `std::sys::unix::ext` -> `std::os` - // - // This is correct, as the visible parent of `std::sys::unix::ext` is in fact - // `std::os`. - // - // When printing the path to `CommandExt` and looking at the `cur_def_key` that - // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go - // to the parent - resulting in a mangled path like - // `std::os::ext::process::CommandExt`. - // - // Instead, we must detect that there was a re-export and instead print `unix` - // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To - // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with - // the visible parent (`std::os`). If these do not match, then we iterate over - // the children of the visible parent (as was done when computing - // `visible_parent_map`), looking for the specific child we currently have and then - // have access to the re-exported name. - DefPathData::Module(actual_name) | - DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - self.tcx.item_children(visible_parent) - .iter() - .find(|child| child.def.def_id() == def_id) - .map(|child| child.ident.as_str()) - .unwrap_or_else(|| actual_name.as_str()) - } - _ => { - data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { - // Re-exported `extern crate` (#43189). - if let DefPathData::CrateRoot = data { - self.tcx.original_crate_name(def_id.krate).as_str() - } else { - Symbol::intern("").as_str() - } - }) - }, - }; - debug!("try_print_visible_def_path: symbol={:?}", symbol); - Some(self.path_append(path, &symbol)) - } -} - -impl ItemPathPrinter for LocalPathPrinter { - type Path = String; - - fn print_def_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> Self::Path { - self.try_print_visible_def_path(def_id, ns) - .unwrap_or_else(|| self.default_print_def_path(def_id, substs, ns)) - } - fn print_impl_path( - self: &mut PrintCx<'_, '_, 'tcx, Self>, - impl_def_id: DefId, - substs: Option>, - ns: Namespace, - ) -> Self::Path { - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = !impl_def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); - let path = self.print_def_path(parent_def_id, None, ns); - let span = self.tcx.def_span(impl_def_id); - return self.path_append(path, &format!("", span)); - } - - self.default_print_impl_path(impl_def_id, substs, ns) - } - - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - if cnum == LOCAL_CRATE { - if self.tcx.sess.rust_2018() { - // We add the `crate::` keyword on Rust 2018, only when desired. - if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - return keywords::Crate.name().to_string(); - } - } - String::new() - } else { - self.tcx.crate_name(cnum).to_string() - } - } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - text.to_string() - } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, - text: &str, - ) -> Self::Path { - if !path.is_empty() { - path.push_str("::"); - } - path.push_str(text); - path - } -} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4f933bf0d538d..882e2dc62b1c3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -95,7 +95,6 @@ mod erase_regions; pub mod fast_reject; pub mod fold; pub mod inhabitedness; -pub mod item_path; pub mod layout; pub mod _match; pub mod outlives; diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index a1d93bc4140cc..053a7531cadd6 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -1,11 +1,64 @@ -use crate::ty::{self, TyCtxt, TypeFoldable}; +use crate::hir::def::Namespace; +use crate::hir::map::DefPathData; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; +use crate::ty::subst::{Subst, SubstsRef}; +use crate::middle::cstore::{ExternCrate, ExternCrateSource}; +use syntax::ast; +use syntax::symbol::{keywords, Symbol}; use rustc_data_structures::fx::FxHashSet; use syntax::symbol::InternedString; +use std::cell::Cell; use std::fmt; use std::ops::Deref; +thread_local! { + static FORCE_ABSOLUTE: Cell = Cell::new(false); + static FORCE_IMPL_FILENAME_LINE: Cell = Cell::new(false); + static SHOULD_PREFIX_WITH_CRATE: Cell = Cell::new(false); +} + +/// Enforces that def_path_str always returns an absolute path and +/// also enables "type-based" impl paths. This is used when building +/// symbols that contain types, where we want the crate name to be +/// part of the symbol. +pub fn with_forced_absolute_paths R, R>(f: F) -> R { + FORCE_ABSOLUTE.with(|force| { + let old = force.get(); + force.set(true); + let result = f(); + force.set(old); + result + }) +} + +/// Force us to name impls with just the filename/line number. We +/// normally try to use types. But at some points, notably while printing +/// cycle errors, this can result in extra or suboptimal error output, +/// so this variable disables that check. +pub fn with_forced_impl_filename_line R, R>(f: F) -> R { + FORCE_IMPL_FILENAME_LINE.with(|force| { + let old = force.get(); + force.set(true); + let result = f(); + force.set(old); + result + }) +} + +/// Adds the `crate::` prefix to paths where appropriate. +pub fn with_crate_prefix R, R>(f: F) -> R { + SHOULD_PREFIX_WITH_CRATE.with(|flag| { + let old = flag.get(); + flag.set(true); + let result = f(); + flag.set(old); + result + }) +} + // FIXME(eddyb) this module uses `pub(crate)` for things used only // from `ppaux` - when that is removed, they can be re-privatized. @@ -89,6 +142,511 @@ pub trait Print<'tcx, P> { } } +pub trait Printer: Sized { + type Path; + + fn print_def_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> Self::Path { + self.default_print_def_path(def_id, substs, ns) + } + fn print_impl_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> Self::Path { + self.default_print_impl_path(impl_def_id, substs, ns) + } + + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + path: Self::Path, + text: &str, + ) -> Self::Path; +} + +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. It is relative to the current crate + /// root, unless with_forced_absolute_paths was used. + pub fn def_path_str_with_substs_and_ns( + self, + def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> String { + debug!("def_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); + if FORCE_ABSOLUTE.with(|force| force.get()) { + PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns) + } else { + PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns) + } + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. It is relative to the current crate + /// root, unless with_forced_absolute_paths was used. + pub fn def_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + self.def_path_str_with_substs_and_ns(def_id, None, ns) + } + + /// Returns a string identifying this local node-id. + // FIXME(eddyb) remove in favor of calling `def_path_str` directly. + pub fn node_path_str(self, id: ast::NodeId) -> String { + self.def_path_str(self.hir().local_def_id(id)) + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. It always begins with a crate identifier. + pub fn absolute_def_path_str(self, def_id: DefId) -> String { + debug!("absolute_def_path_str: def_id={:?}", def_id); + let ns = self.guess_def_namespace(def_id); + PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, None, ns) + } +} + +impl PrintCx<'a, 'gcx, 'tcx, P> { + pub fn default_print_def_path( + &mut self, + def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> P::Path { + debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); + let key = self.tcx.def_key(def_id); + debug!("default_print_def_path: key={:?}", key); + match key.disambiguated_data.data { + DefPathData::CrateRoot => { + assert!(key.parent.is_none()); + self.path_crate(def_id.krate) + } + + DefPathData::Impl => { + self.print_impl_path(def_id, substs, ns) + } + + // Unclear if there is any value in distinguishing these. + // Probably eventually (and maybe we would even want + // finer-grained distinctions, e.g., between enum/struct). + data @ DefPathData::Misc | + data @ DefPathData::TypeNs(..) | + data @ DefPathData::Trait(..) | + data @ DefPathData::TraitAlias(..) | + data @ DefPathData::AssocTypeInTrait(..) | + data @ DefPathData::AssocTypeInImpl(..) | + data @ DefPathData::AssocExistentialInImpl(..) | + data @ DefPathData::ValueNs(..) | + data @ DefPathData::Module(..) | + data @ DefPathData::TypeParam(..) | + data @ DefPathData::LifetimeParam(..) | + data @ DefPathData::ConstParam(..) | + data @ DefPathData::EnumVariant(..) | + data @ DefPathData::Field(..) | + data @ DefPathData::AnonConst | + data @ DefPathData::MacroDef(..) | + data @ DefPathData::ClosureExpr | + data @ DefPathData::ImplTrait | + data @ DefPathData::GlobalMetaData(..) => { + let parent_did = self.tcx.parent(def_id).unwrap(); + let path = self.print_def_path(parent_did, None, ns); + self.path_append(path, &data.as_interned_str().as_symbol().as_str()) + }, + + DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` + let parent_def_id = self.tcx.parent(def_id).unwrap(); + self.print_def_path(parent_def_id, substs, ns) + } + } + } + + fn default_print_impl_path( + &mut self, + impl_def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> P::Path { + debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); + let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); + + // Decide whether to print the parent path for the impl. + // Logically, since impls are global, it's never needed, but + // users may find it useful. Currently, we omit the parent if + // the impl is either in the same module as the self-type or + // as the trait. + let mut self_ty = self.tcx.type_of(impl_def_id); + if let Some(substs) = substs { + self_ty = self_ty.subst(self.tcx, substs); + } + let in_self_mod = match characteristic_def_id_of_type(self_ty) { + None => false, + Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), + }; + + let mut impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id); + if let Some(substs) = substs { + impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); + } + let in_trait_mod = match impl_trait_ref { + None => false, + Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), + }; + + if !in_self_mod && !in_trait_mod { + // If the impl is not co-located with either self-type or + // trait-type, then fallback to a format that identifies + // the module more clearly. + let path = self.print_def_path(parent_def_id, None, ns); + if let Some(trait_ref) = impl_trait_ref { + return self.path_append(path, &format!("", trait_ref, self_ty)); + } else { + return self.path_append(path, &format!("", self_ty)); + } + } + + // Otherwise, try to give a good form that would be valid language + // syntax. Preferably using associated item notation. + + if let Some(trait_ref) = impl_trait_ref { + // Trait impls. + return self.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); + } + + // Inherent impls. Try to print `Foo::bar` for an inherent + // impl on `Foo`, but fallback to `::bar` if self-type is + // anything other than a simple path. + match self_ty.sty { + ty::Adt(adt_def, substs) => { + // FIXME(eddyb) this should recurse to build the path piecewise. + // self.print_def_path(adt_def.did, Some(substs), ns) + let mut s = String::new(); + crate::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap(); + self.path_impl(&s) + } + + ty::Foreign(did) => self.print_def_path(did, None, ns), + + ty::Bool | + ty::Char | + ty::Int(_) | + ty::Uint(_) | + ty::Float(_) | + ty::Str => { + self.path_impl(&self_ty.to_string()) + } + + _ => { + self.path_impl(&format!("<{}>", self_ty)) + } + } + } +} + +/// As a heuristic, when we see an impl, if we see that the +/// 'self type' is a type defined in the same module as the impl, +/// we can omit including the path to the impl itself. This +/// function tries to find a "characteristic `DefId`" for a +/// type. It's just a heuristic so it makes some questionable +/// decisions and we may want to adjust it later. +pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { + match ty.sty { + ty::Adt(adt_def, _) => Some(adt_def.did), + + ty::Dynamic(data, ..) => data.principal_def_id(), + + ty::Array(subty, _) | + ty::Slice(subty) => characteristic_def_id_of_type(subty), + + ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty), + + ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty), + + ty::Tuple(ref tys) => tys.iter() + .filter_map(|ty| characteristic_def_id_of_type(ty)) + .next(), + + ty::FnDef(def_id, _) | + ty::Closure(def_id, _) | + ty::Generator(def_id, _, _) | + ty::Foreign(def_id) => Some(def_id), + + ty::Bool | + ty::Char | + ty::Int(_) | + ty::Uint(_) | + ty::Str | + ty::FnPtr(_) | + ty::Projection(_) | + ty::Placeholder(..) | + ty::UnnormalizedProjection(..) | + ty::Param(_) | + ty::Opaque(..) | + ty::Infer(_) | + ty::Bound(..) | + ty::Error | + ty::GeneratorWitness(..) | + ty::Never | + ty::Float(_) => None, + } +} + +// FIXME(eddyb) remove, alongside `FORCE_ABSOLUTE` and `absolute_def_path_str`. +struct AbsolutePathPrinter; + +impl Printer for AbsolutePathPrinter { + type Path = String; + + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + self.tcx.original_crate_name(cnum).to_string() + } + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { + text.to_string() + } + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { + if !path.is_empty() { + path.push_str("::"); + } + path.push_str(text); + path + } +} + pub struct FmtPrinter { pub fmt: F, } + +// FIXME(eddyb) integrate into `FmtPrinter`. +struct LocalPathPrinter; + +impl LocalPathPrinter { + /// If possible, this returns a global path resolving to `def_id` that is visible + /// from at least one local module and returns true. If the crate defining `def_id` is + /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. + fn try_print_visible_def_path( + self: &mut PrintCx<'_, '_, '_, Self>, + def_id: DefId, + ns: Namespace, + ) -> Option<::Path> { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + + // If `def_id` is a direct or injected extern crate, return the + // path to the crate followed by the path to the item within the crate. + if def_id.index == CRATE_DEF_INDEX { + let cnum = def_id.krate; + + if cnum == LOCAL_CRATE { + return Some(self.path_crate(cnum)); + } + + // In local mode, when we encounter a crate other than + // LOCAL_CRATE, execution proceeds in one of two ways: + // + // 1. for a direct dependency, where user added an + // `extern crate` manually, we put the `extern + // crate` as the parent. So you wind up with + // something relative to the current crate. + // 2. for an extern inferred from a path or an indirect crate, + // where there is no explicit `extern crate`, we just prepend + // the crate name. + match *self.tcx.extern_crate(def_id) { + Some(ExternCrate { + src: ExternCrateSource::Extern(def_id), + direct: true, + span, + .. + }) => { + debug!("try_print_visible_def_path: def_id={:?}", def_id); + let path = if !span.is_dummy() { + self.print_def_path(def_id, None, ns) + } else { + self.path_crate(cnum) + }; + return Some(path); + } + None => { + return Some(self.path_crate(cnum)); + } + _ => {}, + } + } + + if def_id.is_local() { + return None; + } + + let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); + + let mut cur_def_key = self.tcx.def_key(def_id); + debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); + + // For a UnitStruct or TupleStruct we want the name of its parent rather than . + if let DefPathData::StructCtor = cur_def_key.disambiguated_data.data { + let parent = DefId { + krate: def_id.krate, + index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), + }; + + cur_def_key = self.tcx.def_key(parent); + } + + let visible_parent = visible_parent_map.get(&def_id).cloned()?; + let path = self.try_print_visible_def_path(visible_parent, ns)?; + let actual_parent = self.tcx.parent(def_id); + + let data = cur_def_key.disambiguated_data.data; + debug!( + "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}", + data, visible_parent, actual_parent, + ); + + let symbol = match data { + // In order to output a path that could actually be imported (valid and visible), + // we need to handle re-exports correctly. + // + // For example, take `std::os::unix::process::CommandExt`, this trait is actually + // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing). + // + // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is + // private so the "true" path to `CommandExt` isn't accessible. + // + // In this case, the `visible_parent_map` will look something like this: + // + // (child) -> (parent) + // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` + // `std::sys::unix::ext::process` -> `std::sys::unix::ext` + // `std::sys::unix::ext` -> `std::os` + // + // This is correct, as the visible parent of `std::sys::unix::ext` is in fact + // `std::os`. + // + // When printing the path to `CommandExt` and looking at the `cur_def_key` that + // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go + // to the parent - resulting in a mangled path like + // `std::os::ext::process::CommandExt`. + // + // Instead, we must detect that there was a re-export and instead print `unix` + // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To + // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with + // the visible parent (`std::os`). If these do not match, then we iterate over + // the children of the visible parent (as was done when computing + // `visible_parent_map`), looking for the specific child we currently have and then + // have access to the re-exported name. + DefPathData::Module(actual_name) | + DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { + self.tcx.item_children(visible_parent) + .iter() + .find(|child| child.def.def_id() == def_id) + .map(|child| child.ident.as_str()) + .unwrap_or_else(|| actual_name.as_str()) + } + _ => { + data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { + // Re-exported `extern crate` (#43189). + if let DefPathData::CrateRoot = data { + self.tcx.original_crate_name(def_id.krate).as_str() + } else { + Symbol::intern("").as_str() + } + }) + }, + }; + debug!("try_print_visible_def_path: symbol={:?}", symbol); + Some(self.path_append(path, &symbol)) + } +} + +impl Printer for LocalPathPrinter { + type Path = String; + + fn print_def_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> Self::Path { + self.try_print_visible_def_path(def_id, ns) + .unwrap_or_else(|| self.default_print_def_path(def_id, substs, ns)) + } + fn print_impl_path( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + impl_def_id: DefId, + substs: Option>, + ns: Namespace, + ) -> Self::Path { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = !impl_def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` + let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); + let path = self.print_def_path(parent_def_id, None, ns); + let span = self.tcx.def_span(impl_def_id); + return self.path_append(path, &format!("", span)); + } + + self.default_print_impl_path(impl_def_id, substs, ns) + } + + fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + if cnum == LOCAL_CRATE { + if self.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + return keywords::Crate.name().to_string(); + } + } + String::new() + } else { + self.tcx.crate_name(cnum).to_string() + } + } + fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { + text.to_string() + } + fn path_append( + self: &mut PrintCx<'_, '_, '_, Self>, + mut path: Self::Path, + text: &str, + ) -> Self::Path { + if !path.is_empty() { + path.push_str("::"); + } + path.push_str(text); + path + } +} diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e3276ba0bea7b..cff99f23d0e95 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -4,11 +4,10 @@ use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; use crate::ty::tls; -use crate::ty::{TyCtxt}; +use crate::ty::{self, TyCtxt}; use crate::ty::query::Query; use crate::ty::query::config::{QueryConfig, QueryDescription}; use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo}; -use crate::ty::item_path; use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg}; @@ -299,7 +298,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // sometimes cycles itself, leading to extra cycle errors. // (And cycle errors around impls tend to occur during the // collect/coherence phases anyhow.) - item_path::with_forced_impl_filename_line(|| { + ty::print::with_forced_impl_filename_line(|| { let span = fix_span(stack[1 % stack.len()].span, &stack[0].query); let mut err = struct_span_err!(self.sess, span, diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 1417cbf126558..b417091704d72 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -93,8 +93,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::item_path::{self, ItemPathPrinter}; -use rustc::ty::print::PrintCx; +use rustc::ty::print::{PrintCx, Printer}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -225,7 +224,7 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - item_path::with_forced_absolute_paths(|| { + ty::print::with_forced_absolute_paths(|| { PrintCx::new(tcx, SymbolPathPrinter) .print_def_path(def_id, None, Namespace::ValueNS) .into_interned() @@ -400,7 +399,7 @@ impl SymbolPath { struct SymbolPathPrinter; -impl ItemPathPrinter for SymbolPathPrinter { +impl Printer for SymbolPathPrinter { type Path = SymbolPath; fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index c0e2186d9f34c..4a2c05b201328 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -104,7 +104,7 @@ use rustc::hir::map::DefPathData; use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder}; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::ty::{self, TyCtxt, InstanceDef}; -use rustc::ty::item_path::characteristic_def_id_of_type; +use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; use rustc::util::common::time; use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet}; diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 200089530c152..cbdd50cf4052a 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -29,7 +29,7 @@ use rustc::mir::visit::{ }; use rustc::mir::Local; use rustc::mir::*; -use rustc::ty::{item_path, TyCtxt}; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; @@ -265,7 +265,7 @@ pub fn dump_mir<'a, 'tcx>( if !dump_enabled(tcx, pass_name, source) { return; } - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below tcx.def_path_str(source.def_id()) }); diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 12d4e90c7c002..a76d26a6831c2 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -2,7 +2,6 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; -use rustc::ty::item_path; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use std::fmt::Display; @@ -78,7 +77,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>( return; } - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below tcx.def_path_str(source.def_id()) }); @@ -103,7 +102,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>( None => return false, Some(ref filters) => filters, }; - let node_path = item_path::with_forced_impl_filename_line(|| { + let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below tcx.def_path_str(source.def_id()) }); @@ -612,7 +611,7 @@ fn write_mir_sig( _ => bug!("Unexpected def description {:?}", descr), } - item_path::with_forced_impl_filename_line(|| { + ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere write!(w, " {}", tcx.def_path_str(src.def_id())) })?; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f784a720b19c4..b4a1a2d76c262 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -15,7 +15,7 @@ use rustc::hir::print; use rustc::infer::type_variable::TypeVariableOrigin; use rustc::traits::Obligation; use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; -use rustc::ty::item_path::with_crate_prefix; +use rustc::ty::print::with_crate_prefix; use syntax_pos::{Span, FileName}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 08d165b82b1db..6cf8a9896d513 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4225,12 +4225,11 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { pub fn get_path_for_type(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path where F: Fn(DefId) -> Def { - use rustc::ty::item_path::ItemPathPrinter; - use rustc::ty::print::PrintCx; + use rustc::ty::print::{PrintCx, Printer}; struct AbsolutePathPrinter; - impl ItemPathPrinter for AbsolutePathPrinter { + impl Printer for AbsolutePathPrinter { type Path = Vec; fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { From b0fbca953fbdcef5e561a97e5936db0dd13c41d2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 19 Dec 2018 14:49:32 +0200 Subject: [PATCH 108/157] rustc: integrate LocalPathPrinter's behavior into FmtPrinter. --- src/librustc/ty/print.rs | 67 ++++++++++++++++++++++++++++---------- src/librustc/util/ppaux.rs | 35 ++++++++------------ 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index 053a7531cadd6..de0c3ee7fff8e 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet; use syntax::symbol::InternedString; use std::cell::Cell; -use std::fmt; +use std::fmt::{self, Write as _}; use std::ops::Deref; thread_local! { @@ -145,6 +145,7 @@ pub trait Print<'tcx, P> { pub trait Printer: Sized { type Path; + #[must_use] fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, @@ -153,6 +154,7 @@ pub trait Printer: Sized { ) -> Self::Path { self.default_print_def_path(def_id, substs, ns) } + #[must_use] fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, @@ -162,8 +164,11 @@ pub trait Printer: Sized { self.default_print_impl_path(impl_def_id, substs, ns) } + #[must_use] fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; + #[must_use] fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; + #[must_use] fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, path: Self::Path, @@ -171,6 +176,14 @@ pub trait Printer: Sized { ) -> Self::Path; } +#[must_use] +pub struct PrettyPath { + pub empty: bool, +} + +/// Trait for printers that pretty-print using `fmt::Write` to the printer. +pub trait PrettyPrinter: Printer> + fmt::Write {} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always // (but also some things just print a `DefId` generally so maybe we need this?) @@ -202,7 +215,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if FORCE_ABSOLUTE.with(|force| force.get()) { PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns) } else { - PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns) + let mut s = String::new(); + let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) + .print_def_path(def_id, substs, ns); + s } } @@ -442,10 +458,7 @@ pub struct FmtPrinter { pub fmt: F, } -// FIXME(eddyb) integrate into `FmtPrinter`. -struct LocalPathPrinter; - -impl LocalPathPrinter { +impl FmtPrinter { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. @@ -582,8 +595,14 @@ impl LocalPathPrinter { } } -impl Printer for LocalPathPrinter { - type Path = String; +impl fmt::Write for FmtPrinter { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.fmt.write_str(s) + } +} + +impl Printer for FmtPrinter { + type Path = Result; fn print_def_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -612,7 +631,6 @@ impl Printer for LocalPathPrinter { // If no type info is available, fall back to // pretty printing some span information. This should // only occur very early in the compiler pipeline. - // FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)` let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); let path = self.print_def_path(parent_def_id, None, ns); let span = self.tcx.def_span(impl_def_id); @@ -627,26 +645,39 @@ impl Printer for LocalPathPrinter { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - return keywords::Crate.name().to_string(); + write!(self.printer, "{}", keywords::Crate.name())?; + return Ok(PrettyPath { empty: false }); } } - String::new() + Ok(PrettyPath { empty: true }) } else { - self.tcx.crate_name(cnum).to_string() + write!(self.printer, "{}", self.tcx.crate_name(cnum))?; + Ok(PrettyPath { empty: false }) } } fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - text.to_string() + write!(self.printer, "{}", text)?; + Ok(PrettyPath { empty: false }) } fn path_append( self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, + path: Self::Path, text: &str, ) -> Self::Path { - if !path.is_empty() { - path.push_str("::"); + let path = path?; + + // FIXME(eddyb) this shouldn't happen, but is currently + // the case for `extern { ... }` "foreign modules". + if text.is_empty() { + return Ok(path); } - path.push_str(text); - path + + if !path.empty { + write!(self.printer, "::")?; + } + write!(self.printer, "{}", text)?; + Ok(PrettyPath { empty: false }) } } + +impl PrettyPrinter for FmtPrinter {} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index cf92ab2f2ff47..39e26f13233b3 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -10,11 +10,11 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, ParamConst, Ty, TypeFoldable}; -use crate::ty::print::{FmtPrinter, PrintCx, Print}; +use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print}; use crate::mir::interpret::ConstValue; use std::cell::Cell; -use std::fmt; +use std::fmt::{self, Write as _}; use std::iter; use std::usize; @@ -193,18 +193,18 @@ macro_rules! gen_display_debug { } macro_rules! gen_print_impl { ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { - impl<$($x)+, F: fmt::Write> Print<'tcx, FmtPrinter> for $target { + impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { type Output = fmt::Result; - fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter>) -> fmt::Result { + fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { if $cx.is_debug $dbg else $disp } } }; ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { - impl Print<'tcx, FmtPrinter> for $target { + impl Print<'tcx, P> for $target { type Output = fmt::Result; - fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter>) -> fmt::Result { + fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { if $cx.is_debug $dbg else $disp } @@ -235,7 +235,7 @@ macro_rules! define_print { ( $generic:tt $target:ty, ($self:ident, $cx:ident) { display $disp:block } ) => { gen_print_impl! { $generic $target, ($self, $cx) yes $disp no { - write!($cx.printer.fmt, "{:?}", $self) + write!($cx.printer, "{:?}", $self) } } }; } @@ -246,7 +246,7 @@ macro_rules! define_print_multi { } macro_rules! print_inner { ( $cx:expr, write ($($data:expr),+) ) => { - write!($cx.printer.fmt, $($data),+) + write!($cx.printer, $($data),+) }; ( $cx:expr, $kind:ident ($data:expr) ) => { $data.$kind($cx) @@ -258,7 +258,7 @@ macro_rules! print { }; } -impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { +impl PrintCx<'a, 'gcx, 'tcx, P> { fn fn_sig( &mut self, inputs: &[Ty<'tcx>], @@ -409,7 +409,7 @@ impl PrintCx<'a, 'gcx, 'tcx, FmtPrinter> { } fn in_binder(&mut self, value: &ty::Binder) -> fmt::Result - where T: Print<'tcx, FmtPrinter, Output = fmt::Result> + TypeFoldable<'tcx> + where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx> { fn name_by_region_index(index: usize) -> InternedString { match index { @@ -494,13 +494,6 @@ pub fn parameterized( }) } -impl<'a, 'tcx, P, T: Print<'tcx, P>> Print<'tcx, P> for &'a T { - type Output = T::Output; - fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { - (*self).print(cx) - } -} - define_print! { ('tcx) &'tcx ty::List>, (self, cx) { display { @@ -581,7 +574,7 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |cx| { + PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { print!(cx, write("{}", cx.tcx.def_path_str(self.def_id))) }) } @@ -589,7 +582,7 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |cx| { + PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { print!(cx, write("{}", cx.tcx.def_path_str(self.did))) }) } @@ -605,7 +598,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(FmtPrinter { fmt: f }, |cx| { + PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { print!(cx, write("UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, cx.tcx.hir().name_by_hir_id(self.var_path.hir_id), @@ -928,7 +921,7 @@ define_print! { define_print! { () ty::Variance, (self, cx) { debug { - cx.printer.fmt.write_str(match *self { + cx.printer.write_str(match *self { ty::Covariant => "+", ty::Contravariant => "-", ty::Invariant => "o", From a15bfc6f483c552f793932f7ac7fcbb69d187681 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 21 Dec 2018 17:10:21 +0200 Subject: [PATCH 109/157] rustc: merge PrintCx::parameterized and def_path printing. --- src/librustc/infer/error_reporting/mod.rs | 7 +- src/librustc/ty/print.rs | 329 +++++++++++++++------ src/librustc/util/ppaux.rs | 257 ++++++---------- src/librustc_codegen_utils/symbol_names.rs | 182 +++++++----- src/librustdoc/clean/mod.rs | 26 +- src/librustdoc/lib.rs | 1 + src/test/ui/symbol-names/impl1.rs | 2 +- src/test/ui/symbol-names/impl1.stderr | 2 +- 8 files changed, 473 insertions(+), 333 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 2a638853992f3..c99ab215b3580 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -450,8 +450,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let exp_path = self.tcx.def_path_str(did1); let found_path = self.tcx.def_path_str(did2); - let exp_abs_path = self.tcx.absolute_def_path_str(did1); - let found_abs_path = self.tcx.absolute_def_path_str(did2); + // HACK(eddyb) switch form `with_forced_absolute_paths` + // to a custom implementation of `ty::print::Printer`. + let (exp_abs_path, found_abs_path) = ty::print::with_forced_absolute_paths(|| { + (self.tcx.def_path_str(did1), self.tcx.def_path_str(did2)) + }); // We compare strings because DefPath can be different // for imported and non-imported crates if exp_path == found_path || exp_abs_path == found_abs_path { diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index de0c3ee7fff8e..45762460f2dbc 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -2,7 +2,7 @@ use crate::hir::def::Namespace; use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; -use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::{keywords, Symbol}; @@ -12,6 +12,7 @@ use syntax::symbol::InternedString; use std::cell::Cell; use std::fmt::{self, Write as _}; +use std::iter; use std::ops::Deref; thread_local! { @@ -151,8 +152,9 @@ pub trait Printer: Sized { def_id: DefId, substs: Option>, ns: Namespace, + projections: impl Iterator>, ) -> Self::Path { - self.default_print_def_path(def_id, substs, ns) + self.default_print_def_path(def_id, substs, ns, projections) } #[must_use] fn print_impl_path( @@ -167,6 +169,12 @@ pub trait Printer: Sized { #[must_use] fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; #[must_use] + fn path_qualified( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Self::Path; + #[must_use] fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path; #[must_use] fn path_append( @@ -174,6 +182,15 @@ pub trait Printer: Sized { path: Self::Path, text: &str, ) -> Self::Path; + #[must_use] + fn path_generic_args( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + path: Self::Path, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + ns: Namespace, + projections: impl Iterator>, + ) -> Self::Path; } #[must_use] @@ -193,6 +210,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { DefPathData::EnumVariant(..) | DefPathData::Field(..) | DefPathData::AnonConst | + DefPathData::ConstParam(..) | DefPathData::ClosureExpr | DefPathData::StructCtor => Namespace::ValueNS, @@ -212,14 +230,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ns: Namespace, ) -> String { debug!("def_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); - if FORCE_ABSOLUTE.with(|force| force.get()) { - PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns) - } else { - let mut s = String::new(); - let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) - .print_def_path(def_id, substs, ns); - s - } + let mut s = String::new(); + let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) + .print_def_path(def_id, substs, ns, iter::empty()); + s } /// Returns a string identifying this `DefId`. This string is @@ -227,7 +241,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// root, unless with_forced_absolute_paths was used. pub fn def_path_str(self, def_id: DefId) -> String { let ns = self.guess_def_namespace(def_id); - self.def_path_str_with_substs_and_ns(def_id, None, ns) + debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); + let mut s = String::new(); + let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s }) + .print_def_path(def_id, None, ns, iter::empty()); + s } /// Returns a string identifying this local node-id. @@ -235,14 +253,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn node_path_str(self, id: ast::NodeId) -> String { self.def_path_str(self.hir().local_def_id(id)) } - - /// Returns a string identifying this `DefId`. This string is - /// suitable for user output. It always begins with a crate identifier. - pub fn absolute_def_path_str(self, def_id: DefId) -> String { - debug!("absolute_def_path_str: def_id={:?}", def_id); - let ns = self.guess_def_namespace(def_id); - PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, None, ns) - } } impl PrintCx<'a, 'gcx, 'tcx, P> { @@ -251,10 +261,12 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { def_id: DefId, substs: Option>, ns: Namespace, + projections: impl Iterator>, ) -> P::Path { debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); let key = self.tcx.def_key(def_id); debug!("default_print_def_path: key={:?}", key); + match key.disambiguated_data.data { DefPathData::CrateRoot => { assert!(key.parent.is_none()); @@ -265,36 +277,46 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { self.print_impl_path(def_id, substs, ns) } - // Unclear if there is any value in distinguishing these. - // Probably eventually (and maybe we would even want - // finer-grained distinctions, e.g., between enum/struct). - data @ DefPathData::Misc | - data @ DefPathData::TypeNs(..) | - data @ DefPathData::Trait(..) | - data @ DefPathData::TraitAlias(..) | - data @ DefPathData::AssocTypeInTrait(..) | - data @ DefPathData::AssocTypeInImpl(..) | - data @ DefPathData::AssocExistentialInImpl(..) | - data @ DefPathData::ValueNs(..) | - data @ DefPathData::Module(..) | - data @ DefPathData::TypeParam(..) | - data @ DefPathData::LifetimeParam(..) | - data @ DefPathData::ConstParam(..) | - data @ DefPathData::EnumVariant(..) | - data @ DefPathData::Field(..) | - data @ DefPathData::AnonConst | - data @ DefPathData::MacroDef(..) | - data @ DefPathData::ClosureExpr | - data @ DefPathData::ImplTrait | - data @ DefPathData::GlobalMetaData(..) => { - let parent_did = self.tcx.parent(def_id).unwrap(); - let path = self.print_def_path(parent_did, None, ns); - self.path_append(path, &data.as_interned_str().as_symbol().as_str()) - }, - - DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}` - let parent_def_id = self.tcx.parent(def_id).unwrap(); - self.print_def_path(parent_def_id, substs, ns) + _ => { + let generics = substs.map(|_| self.tcx.generics_of(def_id)); + let generics_parent = generics.as_ref().and_then(|g| g.parent); + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let path = if let Some(generics_parent_def_id) = generics_parent { + assert_eq!(parent_def_id, generics_parent_def_id); + + // FIXME(eddyb) try to move this into the parent's printing + // logic, instead of doing it when printing the child. + let parent_generics = self.tcx.generics_of(parent_def_id); + let parent_has_own_self = + parent_generics.has_self && parent_generics.parent_count == 0; + if let (Some(substs), true) = (substs, parent_has_own_self) { + let trait_ref = ty::TraitRef::new(parent_def_id, substs); + self.path_qualified(trait_ref.self_ty(), Some(trait_ref)) + } else { + self.print_def_path(parent_def_id, substs, ns, iter::empty()) + } + } else { + self.print_def_path(parent_def_id, None, ns, iter::empty()) + }; + let path = match key.disambiguated_data.data { + // Skip `::{{constructor}}` on tuple/unit structs. + DefPathData::StructCtor => path, + + _ => { + self.path_append( + path, + &key.disambiguated_data.data.as_interned_str().as_str(), + ) + } + }; + + if let (Some(generics), Some(substs)) = (generics, substs) { + let has_own_self = generics.has_self && generics.parent_count == 0; + let params = &generics.params[has_own_self as usize..]; + self.path_generic_args(path, params, substs, ns, projections) + } else { + path + } } } } @@ -335,7 +357,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // If the impl is not co-located with either self-type or // trait-type, then fallback to a format that identifies // the module more clearly. - let path = self.print_def_path(parent_def_id, None, ns); + let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); if let Some(trait_ref) = impl_trait_ref { return self.path_append(path, &format!("", trait_ref, self_ty)); } else { @@ -348,7 +370,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { if let Some(trait_ref) = impl_trait_ref { // Trait impls. - return self.path_impl(&format!("<{} as {}>", self_ty, trait_ref)); + return self.path_qualified(self_ty, Some(trait_ref)); } // Inherent impls. Try to print `Foo::bar` for an inherent @@ -356,14 +378,10 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { // anything other than a simple path. match self_ty.sty { ty::Adt(adt_def, substs) => { - // FIXME(eddyb) this should recurse to build the path piecewise. - // self.print_def_path(adt_def.did, Some(substs), ns) - let mut s = String::new(); - crate::util::ppaux::parameterized(&mut s, adt_def.did, substs, ns).unwrap(); - self.path_impl(&s) + self.print_def_path(adt_def.did, Some(substs), ns, iter::empty()) } - ty::Foreign(did) => self.print_def_path(did, None, ns), + ty::Foreign(did) => self.print_def_path(did, None, ns, iter::empty()), ty::Bool | ty::Char | @@ -375,7 +393,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { } _ => { - self.path_impl(&format!("<{}>", self_ty)) + self.path_qualified(self_ty, None) } } } @@ -429,44 +447,15 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { } } -// FIXME(eddyb) remove, alongside `FORCE_ABSOLUTE` and `absolute_def_path_str`. -struct AbsolutePathPrinter; - -impl Printer for AbsolutePathPrinter { - type Path = String; - - fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { - self.tcx.original_crate_name(cnum).to_string() - } - fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { - text.to_string() - } - fn path_append( - self: &mut PrintCx<'_, '_, '_, Self>, - mut path: Self::Path, - text: &str, - ) -> Self::Path { - if !path.is_empty() { - path.push_str("::"); - } - path.push_str(text); - path - } -} - pub struct FmtPrinter { pub fmt: F, } -impl FmtPrinter { +impl PrintCx<'a, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path( - self: &mut PrintCx<'_, '_, '_, Self>, - def_id: DefId, - ns: Namespace, - ) -> Option<::Path> { + fn try_print_visible_def_path(&mut self, def_id: DefId) -> Option { debug!("try_print_visible_def_path: def_id={:?}", def_id); // If `def_id` is a direct or injected extern crate, return the @@ -497,7 +486,7 @@ impl FmtPrinter { }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); let path = if !span.is_dummy() { - self.print_def_path(def_id, None, ns) + self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) } else { self.path_crate(cnum) }; @@ -530,7 +519,7 @@ impl FmtPrinter { } let visible_parent = visible_parent_map.get(&def_id).cloned()?; - let path = self.try_print_visible_def_path(visible_parent, ns)?; + let path = self.try_print_visible_def_path(visible_parent)?; let actual_parent = self.tcx.parent(def_id); let data = cur_def_key.disambiguated_data.data; @@ -593,6 +582,114 @@ impl FmtPrinter { debug!("try_print_visible_def_path: symbol={:?}", symbol); Some(self.path_append(path, &symbol)) } + + pub fn pretty_path_qualified( + &mut self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> P::Path { + write!(self.printer, "<")?; + self_ty.print_display(self)?; + if let Some(trait_ref) = trait_ref { + write!(self.printer, " as ")?; + let _ = self.print_def_path( + trait_ref.def_id, + Some(trait_ref.substs), + Namespace::TypeNS, + iter::empty(), + )?; + } + write!(self.printer, ">")?; + Ok(PrettyPath { empty: false }) + } + + pub fn pretty_path_generic_args( + &mut self, + path: P::Path, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + ns: Namespace, + projections: impl Iterator>, + ) -> P::Path { + let path = path?; + + let mut empty = true; + let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { + if empty { + empty = false; + write!(cx.printer, "{}", start) + } else { + write!(cx.printer, "{}", cont) + } + }; + + let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; + + // Don't print any regions if they're all erased. + let print_regions = params.iter().any(|param| { + match substs[param.index as usize].unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + + // Don't print args that are the defaults of their respective parameters. + let num_supplied_defaults = if self.is_verbose { + 0 + } else { + params.iter().rev().take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default && substs[param.index as usize] == Kind::from( + self.tcx.type_of(param.def_id).subst(self.tcx, substs) + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) + } + }).count() + }; + + for param in ¶ms[..params.len() - num_supplied_defaults] { + match substs[param.index as usize].unpack() { + UnpackedKind::Lifetime(region) => { + if !print_regions { + continue; + } + start_or_continue(self, start, ", ")?; + if !region.display_outputs_anything(self) { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + write!(self.printer, "'_")?; + } else { + region.print_display(self)?; + } + } + UnpackedKind::Type(ty) => { + start_or_continue(self, start, ", ")?; + ty.print_display(self)?; + } + UnpackedKind::Const(ct) => { + start_or_continue(self, start, ", ")?; + ct.print_display(self)?; + } + } + } + + for projection in projections { + start_or_continue(self, start, ", ")?; + write!(self.printer, "{}=", + self.tcx.associated_item(projection.item_def_id).ident)?; + projection.ty.print_display(self)?; + } + + start_or_continue(self, "", ">")?; + + Ok(path) + } } impl fmt::Write for FmtPrinter { @@ -609,9 +706,27 @@ impl Printer for FmtPrinter { def_id: DefId, substs: Option>, ns: Namespace, + projections: impl Iterator>, ) -> Self::Path { - self.try_print_visible_def_path(def_id, ns) - .unwrap_or_else(|| self.default_print_def_path(def_id, substs, ns)) + // FIXME(eddyb) avoid querying `tcx.generics_of` + // both here and in `default_print_def_path`. + let generics = substs.map(|_| self.tcx.generics_of(def_id)); + if // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` + !FORCE_ABSOLUTE.with(|force| force.get()) && + generics.as_ref().and_then(|g| g.parent).is_none() { + if let Some(path) = self.try_print_visible_def_path(def_id) { + let path = if let (Some(generics), Some(substs)) = (generics, substs) { + let has_own_self = generics.has_self && generics.parent_count == 0; + let params = &generics.params[has_own_self as usize..]; + self.path_generic_args(path, params, substs, ns, projections) + } else { + path + }; + return path; + } + } + + self.default_print_def_path(def_id, substs, ns, projections) } fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, @@ -621,7 +736,9 @@ impl Printer for FmtPrinter { ) -> Self::Path { // Always use types for non-local impls, where types are always // available, and filename/line-number is mostly uninteresting. - let use_types = !impl_def_id.is_local() || { + let use_types = // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` + FORCE_ABSOLUTE.with(|force| force.get()) || + !impl_def_id.is_local() || { // Otherwise, use filename/line-number if forced. let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); !force_no_types @@ -632,7 +749,7 @@ impl Printer for FmtPrinter { // pretty printing some span information. This should // only occur very early in the compiler pipeline. let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); - let path = self.print_def_path(parent_def_id, None, ns); + let path = self.print_def_path(parent_def_id, None, ns, iter::empty()); let span = self.tcx.def_span(impl_def_id); return self.path_append(path, &format!("", span)); } @@ -641,6 +758,11 @@ impl Printer for FmtPrinter { } fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { + // HACK(eddyb) remove the `FORCE_ABSOLUTE` hack by bypassing `FmtPrinter` + if FORCE_ABSOLUTE.with(|force| force.get()) { + write!(self.printer, "{}", self.tcx.original_crate_name(cnum))?; + return Ok(PrettyPath { empty: false }); + } if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { // We add the `crate::` keyword on Rust 2018, only when desired. @@ -655,6 +777,13 @@ impl Printer for FmtPrinter { Ok(PrettyPath { empty: false }) } } + fn path_qualified( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Self::Path { + self.pretty_path_qualified(self_ty, trait_ref) + } fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path { write!(self.printer, "{}", text)?; Ok(PrettyPath { empty: false }) @@ -678,6 +807,16 @@ impl Printer for FmtPrinter { write!(self.printer, "{}", text)?; Ok(PrettyPath { empty: false }) } + fn path_generic_args( + self: &mut PrintCx<'_, '_, 'tcx, Self>, + path: Self::Path, + params: &[ty::GenericParamDef], + substs: SubstsRef<'tcx>, + ns: Namespace, + projections: impl Iterator>, + ) -> Self::Path { + self.pretty_path_generic_args(path, params, substs, ns, projections) + } } impl PrettyPrinter for FmtPrinter {} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 39e26f13233b3..2c38c437cf6e7 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1,8 +1,7 @@ use crate::hir::def::Namespace; use crate::hir::def_id::DefId; -use crate::hir::map::definitions::DefPathData; use crate::middle::region; -use crate::ty::subst::{self, Kind, Subst, SubstsRef, UnpackedKind}; +use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind}; use crate::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use crate::ty::{Bool, Char, Adt}; use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; @@ -10,7 +9,7 @@ use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use crate::ty::{self, ParamConst, Ty, TypeFoldable}; -use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print}; +use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer}; use crate::mir::interpret::ConstValue; use std::cell::Cell; @@ -284,130 +283,6 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { Ok(()) } - fn parameterized( - &mut self, - def_id: DefId, - substs: SubstsRef<'tcx>, - ns: Namespace, - projections: impl Iterator>, - ) -> fmt::Result { - let key = self.tcx.def_key(def_id); - let generics = self.tcx.generics_of(def_id); - - if let Some(parent_def_id) = generics.parent { - assert_eq!(parent_def_id, DefId { index: key.parent.unwrap(), ..def_id }); - - let parent_generics = self.tcx.generics_of(parent_def_id); - let parent_has_own_self = - parent_generics.has_self && parent_generics.parent_count == 0; - if parent_has_own_self { - print!(self, write("<"), print_display(substs.type_at(0)), write(" as "))?; - self.parameterized(parent_def_id, substs, Namespace::TypeNS, iter::empty())?; - print!(self, write(">"))?; - } else { - self.parameterized(parent_def_id, substs, ns, iter::empty())?; - } - - // Skip `::{{constructor}}` on tuple/unit structs. - match key.disambiguated_data.data { - DefPathData::StructCtor => {} - - _ => { - print!(self, write("::{}", key.disambiguated_data.data.as_interned_str()))?; - } - } - } else { - // FIXME(eddyb) recurse through printing a path via `self`, instead - // instead of using the `tcx` method that produces a `String`. - print!(self, write("{}", - self.tcx.def_path_str_with_substs_and_ns(def_id, Some(substs), ns)))?; - - // For impls, the above call already prints relevant generics args. - if let DefPathData::Impl = key.disambiguated_data.data { - return Ok(()); - } - } - - let mut empty = true; - let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - if empty { - empty = false; - print!(cx, write("{}", start)) - } else { - print!(cx, write("{}", cont)) - } - }; - - let start = if ns == Namespace::ValueNS { "::<" } else { "<" }; - - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; - - // Don't print any regions if they're all erased. - let print_regions = params.iter().any(|param| { - match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(r) => *r != ty::ReErased, - _ => false, - } - }); - - // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = if self.is_verbose { - 0 - } else { - params.iter().rev().take_while(|param| { - match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default && substs[param.index as usize] == Kind::from( - self.tcx.type_of(param.def_id).subst(self.tcx, substs) - ) - } - ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) - } - }).count() - }; - - for param in ¶ms[..params.len() - num_supplied_defaults] { - match substs[param.index as usize].unpack() { - UnpackedKind::Lifetime(region) => { - if !print_regions { - continue; - } - start_or_continue(self, start, ", ")?; - if !region.display_outputs_anything(self) { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - print!(self, write("'_"))?; - } else { - region.print_display(self)?; - } - } - UnpackedKind::Type(ty) => { - start_or_continue(self, start, ", ")?; - ty.print_display(self)?; - } - UnpackedKind::Const(ct) => { - start_or_continue(self, start, ", ")?; - ct.print_display(self)?; - } - } - } - - for projection in projections { - start_or_continue(self, start, ", ")?; - print!(self, - write("{}=", - self.tcx.associated_item(projection.item_def_id).ident), - print_display(projection.ty))?; - } - - start_or_continue(self, "", ">") - } - fn in_binder(&mut self, value: &ty::Binder) -> fmt::Result where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx> { @@ -490,7 +365,8 @@ pub fn parameterized( ) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.parameterized(did, substs, ns, iter::empty()) + let _ = cx.print_def_path(did, Some(substs), ns, iter::empty())?; + Ok(()) }) } @@ -508,7 +384,12 @@ define_print! { if let Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = self.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - print!(cx, write("{}", cx.tcx.def_path_str(principal.def_id)))?; + let _ = cx.print_def_path( + principal.def_id, + None, + Namespace::TypeNS, + iter::empty(), + )?; cx.fn_sig(args, false, proj.ty)?; resugared_principal = true; } @@ -519,9 +400,9 @@ define_print! { // Use a type that can't appear in defaults of type parameters. let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); let principal = principal.with_self_ty(cx.tcx, dummy_self); - cx.parameterized( + let _ = cx.print_def_path( principal.def_id, - principal.substs, + Some(principal.substs), Namespace::TypeNS, self.projection_bounds(), )?; @@ -530,8 +411,10 @@ define_print! { } // Builtin bounds. + // FIXME(eddyb) avoid printing twice (needed to ensure + // that the auto traits are sorted *and* printed via cx). let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - cx.tcx.def_path_str(did) + (cx.tcx.def_path_str(did), did) }).collect(); // The auto traits come ordered by `DefPathHash`. While @@ -543,13 +426,18 @@ define_print! { // output, sort the auto-traits alphabetically. auto_traits.sort(); - for auto_trait in auto_traits { + for (_, def_id) in auto_traits { if !first { print!(cx, write(" + "))?; } first = false; - print!(cx, write("{}", auto_trait))?; + let _ = cx.print_def_path( + def_id, + None, + Namespace::TypeNS, + iter::empty(), + )?; } Ok(()) @@ -575,7 +463,13 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { - print!(cx, write("{}", cx.tcx.def_path_str(self.def_id))) + let _ = cx.print_def_path( + self.def_id, + None, + Namespace::TypeNS, + iter::empty(), + )?; + Ok(()) }) } } @@ -583,7 +477,13 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { PrintCx::with(FmtPrinter { fmt: f }, |mut cx| { - print!(cx, write("{}", cx.tcx.def_path_str(self.did))) + let _ = cx.print_def_path( + self.did, + None, + Namespace::TypeNS, + iter::empty(), + )?; + Ok(()) }) } } @@ -645,10 +545,10 @@ define_print! { display { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = *ty::Binder::bind(*self) + ty::Binder::bind(*self) .with_self_ty(cx.tcx, dummy_self) - .skip_binder(); - cx.parameterized(trait_ref.def_id, trait_ref.substs, Namespace::TypeNS, iter::empty()) + .skip_binder() + .print_display(cx) } debug { self.print_display(cx) @@ -874,7 +774,8 @@ define_print! { // // NB: this must be kept in sync with the printing logic above. impl ty::RegionKind { - fn display_outputs_anything