From 1244ced9580b942926afc06815e0691cf3f4a846 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Feb 2020 14:33:58 +0100 Subject: [PATCH 01/34] Remove "important traits" feature --- src/doc/rustdoc/src/unstable-features.md | 21 ---- .../src/language-features/doc-spotlight.md | 30 ------ src/librustc_feature/active.rs | 3 - src/librustdoc/clean/inline.rs | 2 - src/librustdoc/clean/mod.rs | 2 - src/librustdoc/clean/types.rs | 1 - src/librustdoc/html/format.rs | 12 --- src/librustdoc/html/render.rs | 85 +--------------- src/librustdoc/html/static/main.js | 28 ------ src/librustdoc/html/static/rustdoc.css | 96 +------------------ src/librustdoc/html/static/themes/dark.css | 33 ------- src/librustdoc/html/static/themes/light.css | 33 ------- src/test/rustdoc/doc-spotlight.rs | 36 ------- .../feature-gate-doc_spotlight.rs | 4 - .../feature-gate-doc_spotlight.stderr | 12 --- 15 files changed, 7 insertions(+), 391 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/doc-spotlight.md delete mode 100644 src/test/rustdoc/doc-spotlight.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-doc_spotlight.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index a48526d39fd0a..cf0280b6ff48c 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -138,27 +138,6 @@ Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg]. [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 -### Adding your trait to the "Important Traits" dialog - -Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when -implemented on it. These traits are intended to be the primary interface for their types, and are -often the only thing available to be documented on their types. For this reason, Rustdoc will track -when a given type implements one of these traits and call special attention to it when a function -returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next -to the function, which, when clicked, shows the dialog. - -In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and -`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a -special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this -attribute to your own trait to include it in the "Important Traits" dialog in documentation. - -The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate. -For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking -issue][issue-spotlight]. - -[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html -[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 - ### Exclude certain dependencies from documentation The standard library uses several dependencies which, in turn, use several types and traits from the diff --git a/src/doc/unstable-book/src/language-features/doc-spotlight.md b/src/doc/unstable-book/src/language-features/doc-spotlight.md deleted file mode 100644 index 8117755fef1c8..0000000000000 --- a/src/doc/unstable-book/src/language-features/doc-spotlight.md +++ /dev/null @@ -1,30 +0,0 @@ -# `doc_spotlight` - -The tracking issue for this feature is: [#45040] - -The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute, -to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]` -attribute to a trait definition will make rustdoc print extra information for functions which return -a type that implements that trait. This attribute is applied to the `Iterator`, `io::Read`, and -`io::Write` traits in the standard library. - -You can do this on your own traits, like this: - -``` -#![feature(doc_spotlight)] - -#[doc(spotlight)] -pub trait MyTrait {} - -pub struct MyStruct; -impl MyTrait for MyStruct {} - -/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`, -/// without having to write that yourself! -pub fn my_fn() -> MyStruct { MyStruct } -``` - -This feature was originally implemented in PR [#45039]. - -[#45040]: https://github.com/rust-lang/rust/issues/45040 -[#45039]: https://github.com/rust-lang/rust/pull/45039 diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 0082f4f1a6e89..1ca3b66580cd1 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -363,9 +363,6 @@ declare_features! ( /// Allows `#[doc(masked)]`. (active, doc_masked, "1.21.0", Some(44027), None), - /// Allows `#[doc(spotlight)]`. - (active, doc_spotlight, "1.22.0", Some(45040), None), - /// Allows `#[doc(include = "some-file")]`. (active, external_doc, "1.22.0", Some(44732), None), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 78222d21b934a..33ee6ffef0ebd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -198,7 +198,6 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { let generics = (cx.tcx.generics_of(did), predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); - let is_spotlight = load_attrs(cx, did).clean(cx).has_doc_flag(sym::spotlight); let is_auto = cx.tcx.trait_is_auto(did); clean::Trait { auto: auto_trait, @@ -206,7 +205,6 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { generics, items: trait_items, bounds: supertrait_bounds, - is_spotlight, is_auto, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index af81087b53ed6..e1406e1637660 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1013,7 +1013,6 @@ impl Clean for hir::FnRetTy<'_> { impl Clean for doctree::Trait<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let attrs = self.attrs.clean(cx); - let is_spotlight = attrs.has_doc_flag(sym::spotlight); Item { name: Some(self.name.clean(cx)), attrs, @@ -1028,7 +1027,6 @@ impl Clean for doctree::Trait<'_> { items: self.items.iter().map(|ti| ti.clean(cx)).collect(), generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), - is_spotlight, is_auto: self.is_auto.clean(cx), }), } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2f220cbc9be8c..ac868afbb6f1c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -952,7 +952,6 @@ pub struct Trait { pub items: Vec, pub generics: Generics, pub bounds: Vec, - pub is_spotlight: bool, pub is_auto: bool, } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index ec615fc858976..e60ff37fd279a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -63,22 +63,10 @@ impl Buffer { Buffer { for_html: false, buffer: String::new() } } - crate fn is_empty(&self) -> bool { - self.buffer.is_empty() - } - crate fn into_inner(self) -> String { self.buffer } - crate fn insert_str(&mut self, idx: usize, s: &str) { - self.buffer.insert_str(idx, s); - } - - crate fn push_str(&mut self, s: &str) { - self.buffer.push_str(s); - } - // Intended for consumption by write! and writeln! (std::fmt) but without // the fmt::Result return type imposed by fmt::Write (and avoiding the trait // import). diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 6a23b230e1224..8e2d593c730ee 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2324,7 +2324,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func f.generics.print() ) .len(); - write!(w, "{}
", render_spotlight_traits(it));
+    write!(w, "
");
     render_attributes(w, it, false);
     write!(
         w,
@@ -2527,13 +2527,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait)
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
         let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-        write!(
-            w,
-            "

{extra}", - extra = render_spotlight_traits(m), - id = id, - ns_id = ns_id - ); + write!(w, "

", id = id, ns_id = ns_id); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); write!(w, ""); render_stability_since(w, m, t); @@ -3519,76 +3513,6 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { } } -fn render_spotlight_traits(item: &clean::Item) -> String { - match item.inner { - clean::FunctionItem(clean::Function { ref decl, .. }) - | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) - | clean::MethodItem(clean::Method { ref decl, .. }) - | clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => spotlight_decl(decl), - _ => String::new(), - } -} - -fn spotlight_decl(decl: &clean::FnDecl) -> String { - let mut out = Buffer::html(); - let mut trait_ = String::new(); - - if let Some(did) = decl.output.def_id() { - let c = cache(); - if let Some(impls) = c.impls.get(&did) { - for i in impls { - let impl_ = i.inner_impl(); - if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) { - if out.is_empty() { - out.push_str(&format!( - "

Important traits for {}

\ - ", - impl_.for_.print() - )); - trait_.push_str(&impl_.for_.print().to_string()); - } - - //use the "where" class here to make it small - out.push_str(&format!( - "{}", - impl_.print() - )); - let t_did = impl_.trait_.def_id().unwrap(); - for it in &impl_.items { - if let clean::TypedefItem(ref tydef, _) = it.inner { - out.push_str(" "); - assoc_type( - &mut out, - it, - &[], - Some(&tydef.type_), - AssocItemLink::GotoSource(t_did, &FxHashSet::default()), - "", - ); - out.push_str(";"); - } - } - } - } - } - } - - if !out.is_empty() { - out.insert_str( - 0, - &format!( - "
ⓘ\ - Important traits for {}
\ -
", - trait_ - ), - ); - out.push_str("
"); - } - - out.into_inner() -} - fn render_impl( w: &mut Buffer, cx: &Context, @@ -3695,14 +3619,13 @@ fn render_impl( (true, " hidden") }; match item.inner { - clean::MethodItem(clean::Method { ref decl, .. }) - | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) => { + clean::MethodItem(clean::Method { .. }) + | clean::TyMethodItem(clean::TyMethod { .. }) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = cx.derive_id(format!("{}.{}", item_type, name)); let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "

", id, item_type, extra_class); - write!(w, "{}", spotlight_decl(decl)); write!(w, "", ns_id); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, ""); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 2870c6e0a6147..a799aed698578 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -341,7 +341,6 @@ function getSearchElement() { function handleEscape(ev) { var help = getHelpElement(); var search = getSearchElement(); - hideModal(); if (hasClass(help, "hidden") === false) { displayHelp(false, ev, help); } else if (hasClass(search, "hidden") === false) { @@ -373,7 +372,6 @@ function getSearchElement() { case "s": case "S": displayHelp(false, ev); - hideModal(); ev.preventDefault(); focusSearchBar(); break; @@ -386,7 +384,6 @@ function getSearchElement() { case "?": if (ev.shiftKey) { - hideModal(); displayHelp(true, ev); } break; @@ -2504,31 +2501,6 @@ function getSearchElement() { lineNumbersFunc(e); }); - function showModal(content) { - var modal = document.createElement("div"); - modal.id = "important"; - addClass(modal, "modal"); - modal.innerHTML = "
✕" + - "
" + content + - "
"; - document.getElementsByTagName("body")[0].appendChild(modal); - document.getElementById("modal-close").onclick = hideModal; - modal.onclick = hideModal; - } - - function hideModal() { - var modal = document.getElementById("important"); - if (modal) { - modal.parentNode.removeChild(modal); - } - } - - onEachLazy(document.getElementsByClassName("important-traits"), function(e) { - e.onclick = function() { - showModal(e.lastElementChild.innerHTML); - }; - }); - // In the search display, allows to switch between tabs. function printTab(nb) { if (nb === 0 || nb === 1 || nb === 2) { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 0dfe82c501469..f05db6c218524 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -143,12 +143,9 @@ code, pre, a.test-arrow { border-radius: 3px; padding: 0 0.1em; } -.docblock pre code, .docblock-short pre code, .docblock code.spotlight { +.docblock pre code, .docblock-short pre code { padding: 0; } -.docblock code.spotlight :last-child { - padding-bottom: 0.6em; -} pre { padding: 14px; } @@ -503,7 +500,7 @@ h4 > code, h3 > code, .invisible > code { font-size: 0.8em; } -.content .methods > div:not(.important-traits) { +.content .methods > div { margin-left: 40px; margin-bottom: 15px; } @@ -1072,7 +1069,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { border-style: solid; } -.important-traits .tooltip .tooltiptext { +.tooltip .tooltiptext { border: 1px solid; } @@ -1117,17 +1114,6 @@ pre.rust { font-size: 16px; } -.important-traits { - cursor: pointer; - z-index: 2; -} - -h4 > .important-traits { - position: absolute; - left: -44px; - top: 2px; -} - #all-types { text-align: center; border: 1px solid; @@ -1354,12 +1340,6 @@ h4 > .important-traits { z-index: 1; } - h4 > .important-traits { - position: absolute; - left: -22px; - top: 24px; - } - #titles > div > div.count { float: left; width: 100%; @@ -1462,82 +1442,12 @@ h4 > .important-traits { } } -.modal { - position: fixed; - width: 100vw; - height: 100vh; - z-index: 10000; - top: 0; - left: 0; -} - -.modal-content { - display: block; - max-width: 60%; - min-width: 200px; - padding: 8px; - top: 40%; - position: absolute; - left: 50%; - transform: translate(-50%, -40%); - border: 1px solid; - border-radius: 4px; - border-top-right-radius: 0; -} - -.modal-content > .docblock { - margin: 0; -} - h3.important { margin: 0; margin-bottom: 13px; font-size: 19px; } -.modal-content > .docblock > code.content { - margin: 0; - padding: 0; - font-size: 20px; -} - -.modal-content > .close { - position: absolute; - font-weight: 900; - right: -25px; - top: -1px; - font-size: 18px; - width: 25px; - padding-right: 2px; - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; - text-align: center; - border: 1px solid; - border-right: 0; - cursor: pointer; -} - -.modal-content > .whiter { - height: 25px; - position: absolute; - width: 3px; - right: -2px; - top: 0px; -} - -#main > div.important-traits { - position: absolute; - left: -24px; - margin-top: 16px; -} - -.content > .methods > .method > div.important-traits { - position: absolute; - font-weight: 400; - left: -42px; - margin-top: 2px; -} - kbd { display: inline-block; padding: 3px 5px; diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 9a0e7bbabcba9..e7041d54c6bfd 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -298,12 +298,6 @@ pre.ignore:hover, .information:hover + pre.ignore { border-color: transparent black transparent transparent; } -.important-traits .tooltip .tooltiptext { - background-color: white; - color: black; - border-color: black; -} - #titles > div:not(.selected) { background-color: #252525; border-top-color: #252525; @@ -317,33 +311,6 @@ pre.ignore:hover, .information:hover + pre.ignore { color: #888; } -.modal { - background-color: rgba(0,0,0,0.3); -} - -.modal-content { - background-color: #272727; - border-color: #999; -} - -.modal-content > .close { - background-color: #272727; - border-color: #999; -} - -.modal-content > .close:hover { - background-color: #ff1f1f; - color: white; -} - -.modal-content > .whiter { - background-color: #272727; -} - -.modal-content > .close:hover + .whiter { - background-color: #ff1f1f; -} - @media (max-width: 700px) { .sidebar-menu { background-color: #505050; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index ca8ea1c456a2c..a1efef6701fd1 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -292,12 +292,6 @@ pre.ignore:hover, .information:hover + pre.ignore { border-color: transparent black transparent transparent; } -.important-traits .tooltip .tooltiptext { - background-color: white; - color: black; - border-color: black; -} - #titles > div:not(.selected) { background-color: #e6e6e6; border-top-color: #e6e6e6; @@ -311,33 +305,6 @@ pre.ignore:hover, .information:hover + pre.ignore { color: #888; } -.modal { - background-color: rgba(0,0,0,0.3); -} - -.modal-content { - background-color: #eee; - border-color: #999; -} - -.modal-content > .close { - background-color: #eee; - border-color: #999; -} - -.modal-content > .close:hover { - background-color: #ff1f1f; - color: white; -} - -.modal-content > .whiter { - background-color: #eee; -} - -.modal-content > .close:hover + .whiter { - background-color: #ff1f1f; -} - @media (max-width: 700px) { .sidebar-menu { background-color: #F1F1F1; diff --git a/src/test/rustdoc/doc-spotlight.rs b/src/test/rustdoc/doc-spotlight.rs deleted file mode 100644 index ddd46c3c2155f..0000000000000 --- a/src/test/rustdoc/doc-spotlight.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![feature(doc_spotlight)] - -pub struct Wrapper { - inner: T, -} - -impl SomeTrait for Wrapper {} - -#[doc(spotlight)] -pub trait SomeTrait { - // @has doc_spotlight/trait.SomeTrait.html - // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' - fn wrap_me(self) -> Wrapper where Self: Sized { - Wrapper { - inner: self, - } - } -} - -pub struct SomeStruct; -impl SomeTrait for SomeStruct {} - -impl SomeStruct { - // @has doc_spotlight/struct.SomeStruct.html - // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' - // @has - '//code[@class="content"]' 'impl SomeTrait for Wrapper' - pub fn new() -> SomeStruct { - SomeStruct - } -} - -// @has doc_spotlight/fn.bare_fn.html -// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' -pub fn bare_fn() -> SomeStruct { - SomeStruct -} diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs b/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs deleted file mode 100644 index 452b45b34456b..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[doc(spotlight)] //~ ERROR: `#[doc(spotlight)]` is experimental -trait SomeTrait {} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr b/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr deleted file mode 100644 index 010d74054a412..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-doc_spotlight.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: `#[doc(spotlight)]` is experimental - --> $DIR/feature-gate-doc_spotlight.rs:1:1 - | -LL | #[doc(spotlight)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #45040 for more information - = help: add `#![feature(doc_spotlight)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 13c6d5819aae3c0de6a90e7f17ea967bf4487cbb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Feb 2020 14:38:30 +0100 Subject: [PATCH 02/34] Remove spotlight usage --- src/libcore/future/future.rs | 1 - src/libcore/iter/traits/iterator.rs | 1 - src/libcore/lib.rs | 1 - src/librustc_ast_passes/feature_gate.rs | 1 - src/librustc_span/symbol.rs | 2 -- src/libstd/io/mod.rs | 2 -- src/libstd/lib.rs | 1 - 7 files changed, 9 deletions(-) diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index f14ed38b9b0f2..00a171e6b5fb1 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -24,7 +24,6 @@ use crate::task::{Context, Poll}; /// `.await` the value. /// /// [`Waker`]: ../task/struct.Waker.html -#[doc(spotlight)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] #[lang = "future_trait"] diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 1d055676c7708..83c9a5fbe15ef 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -92,7 +92,6 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )] -#[doc(spotlight)] #[must_use = "iterators are lazy and do nothing unless consumed"] pub trait Iterator { /// The type of the elements being iterated over. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index bca96b77812c8..21806fad8ff1b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -90,7 +90,6 @@ #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)] -#![feature(doc_spotlight)] #![feature(extern_types)] #![feature(fundamental)] #![feature(intrinsics)] diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 3c924847a7364..2146eec338f71 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -245,7 +245,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { include => external_doc cfg => doc_cfg masked => doc_masked - spotlight => doc_spotlight alias => doc_alias keyword => doc_keyword ); diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 97708d91d7e2a..42e92b60d69f5 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -269,7 +269,6 @@ symbols! { doc_cfg, doc_keyword, doc_masked, - doc_spotlight, doctest, document_private_items, dotdoteq_in_patterns, @@ -688,7 +687,6 @@ symbols! { Some, specialization, speed, - spotlight, sse4a_target_feature, stable, staged_api, diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 67b382c7a845e..1f88a6a5576b6 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -497,7 +497,6 @@ where /// [`&str`]: ../../std/primitive.str.html /// [slice]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -#[doc(spotlight)] pub trait Read { /// Pull some bytes from this source into the specified buffer, returning /// how many bytes were read. @@ -1228,7 +1227,6 @@ impl Initializer { /// /// [`write_all`]: #method.write_all #[stable(feature = "rust1", since = "1.0.0")] -#[doc(spotlight)] pub trait Write { /// Write a buffer into this writer, returning how many bytes were written. /// diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 799585ffc0acf..f482eb6b2eee5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -256,7 +256,6 @@ #![feature(doc_cfg)] #![feature(doc_keyword)] #![feature(doc_masked)] -#![feature(doc_spotlight)] #![feature(dropck_eyepatch)] #![feature(duration_constants)] #![feature(exact_size_is_empty)] From 7859f0eac3b70fea1f129665d0b9f4c56769fa4c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 2 Mar 2020 21:47:33 -0300 Subject: [PATCH 03/34] Make PlaceRef lifetimes of Place::as_ref be both 'tcx --- src/librustc/mir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 668240ab42b4c..0d429d8879bac 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1864,7 +1864,7 @@ impl<'tcx> Place<'tcx> { self.as_ref().as_local() } - pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> { + pub fn as_ref(&self) -> PlaceRef<'tcx, 'tcx> { PlaceRef { local: self.local, projection: &self.projection } } } From 812e62f14609fe80c49664f8b4ee5678c126c4a3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 2 Mar 2020 22:02:52 -0300 Subject: [PATCH 04/34] Make PlaceRef lifetimes of LocalAnalyzer::process_place be both 'tcx --- src/librustc_codegen_ssa/mir/analyze.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 7bf222f4701b7..6214aa84b81d6 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -97,7 +97,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { fn process_place( &mut self, - place_ref: &mir::PlaceRef<'_, 'tcx>, + place_ref: &mir::PlaceRef<'tcx, 'tcx>, context: PlaceContext, location: Location, ) { From 1a1dcfad6fa13f1b2b69b0e111dcad10326d36ea Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 3 Mar 2020 16:55:01 -0300 Subject: [PATCH 05/34] Make PlaceRef lifetimes of codegen_place be both 'tcx --- src/librustc_codegen_ssa/mir/operand.rs | 4 ++-- src/librustc_codegen_ssa/mir/place.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index af95450935caa..96c1351de410c 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -364,7 +364,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn maybe_codegen_consume_direct( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'_, 'tcx>, + place_ref: mir::PlaceRef<'tcx, 'tcx>, ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); @@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_consume( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'_, 'tcx>, + place_ref: mir::PlaceRef<'tcx, 'tcx>, ) -> OperandRef<'tcx, Bx::Value> { debug!("codegen_consume(place_ref={:?})", place_ref); diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index fa82daa0f7d52..0d2749d3f5feb 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_place( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'_, 'tcx>, + place_ref: mir::PlaceRef<'tcx, 'tcx>, ) -> PlaceRef<'tcx, Bx::Value> { debug!("codegen_place(place_ref={:?})", place_ref); let cx = self.cx; From 2af5e87b4b3ef9c7210e4b40ad86a14ff32932f1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 3 Mar 2020 17:00:57 -0300 Subject: [PATCH 06/34] Make PlaceRef lifetimes of monomorphized_place_ty be both 'tcx --- src/librustc_codegen_ssa/mir/place.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 0d2749d3f5feb..3ff0c8dd2aa46 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { result } - pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> { + pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx, 'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); let place_ty = mir::Place::ty_from(place_ref.local, place_ref.projection, *self.mir, tcx); self.monomorphize(&place_ty.ty) From a20d54f00cb4b5386e1b307bc1c990eac02184da Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 3 Mar 2020 17:22:54 -0300 Subject: [PATCH 07/34] Make PlaceRef lifetimes of RootPlace be both 'tcx --- src/librustc_mir/borrow_check/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 28974dcd08bf6..4e21ba86d0996 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -841,9 +841,9 @@ enum InitializationRequiringAction { PartialAssignment, } -struct RootPlace<'d, 'tcx> { +struct RootPlace<'tcx> { place_local: Local, - place_projection: &'d [PlaceElem<'tcx>], + place_projection: &'tcx [PlaceElem<'tcx>], is_local_mutation_allowed: LocalMutationIsAllowed, } @@ -2029,7 +2029,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// Adds the place into the used mutable variables set - fn add_used_mut<'d>(&mut self, root_place: RootPlace<'d, 'tcx>, flow_state: &Flows<'cx, 'tcx>) { + fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'cx, 'tcx>) { match root_place { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being @@ -2063,11 +2063,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Whether this value can be written or borrowed mutably. /// Returns the root place if the place passed in is a projection. - fn is_mutable<'d>( + fn is_mutable( &self, - place: PlaceRef<'d, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, is_local_mutation_allowed: LocalMutationIsAllowed, - ) -> Result, PlaceRef<'d, 'tcx>> { + ) -> Result, PlaceRef<'tcx, 'tcx>> { match place { PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[local]; From 842af362685979e011e0360984dc1ec96ba5b7e9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 11:21:01 -0300 Subject: [PATCH 08/34] Make PlaceRef lifetimes of borrow_conflict_place be both 'tcx --- src/librustc_mir/borrow_check/mod.rs | 5 +++-- src/librustc_mir/borrow_check/places_conflict.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4e21ba86d0996..84c9f733be058 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -86,6 +86,8 @@ crate struct Upvar { mutability: Mutability, } +const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref]; + pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { mir_borrowck, ..*providers }; } @@ -1413,7 +1415,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) { debug!("check_for_invalidation_at_exit({:?})", borrow); let place = &borrow.borrowed_place; - let deref = [ProjectionElem::Deref]; let mut root_place = PlaceRef { local: place.local, projection: &[] }; // FIXME(nll-rfc#40): do more precise destructor tracking here. For now @@ -1427,7 +1428,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Thread-locals might be dropped after the function exits // We have to dereference the outer reference because // borrows don't conflict behind shared references. - root_place.projection = &deref; + root_place.projection = DEREF_PROJECTION; (true, true) } else { (false, self.locals_are_invalidated_at_exit) diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 984de021ca112..1f90b94cfcdc3 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -48,7 +48,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, - access_place: PlaceRef<'_, 'tcx>, + access_place: PlaceRef<'tcx, 'tcx>, access: AccessDepth, bias: PlaceConflictBias, ) -> bool { @@ -73,7 +73,7 @@ fn place_components_conflict<'tcx>( body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, - access_place: PlaceRef<'_, 'tcx>, + access_place: PlaceRef<'tcx, 'tcx>, access: AccessDepth, bias: PlaceConflictBias, ) -> bool { From f54e8634e1394d3436037ff54e0f87739709a916 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 13:00:08 -0300 Subject: [PATCH 09/34] Make PlaceRef lifetimes of move_error_reported be both 'tcx --- .../borrow_check/diagnostics/conflict_errors.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 11 ++++++----- src/librustc_mir/borrow_check/prefixes.rs | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index ca51d16f9f269..9d609411a54bb 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -51,7 +51,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - (moved_place, used_place, span): (PlaceRef<'cx, 'tcx>, PlaceRef<'cx, 'tcx>, Span), + (moved_place, used_place, span): (PlaceRef<'cx, 'tcx>, PlaceRef<'tcx, 'tcx>, Span), mpi: MovePathIndex, ) { debug!( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 84c9f733be058..2d73d96ec8b6a 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -468,7 +468,8 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - move_error_reported: BTreeMap, (PlaceRef<'cx, 'tcx>, DiagnosticBuilder<'cx>)>, + move_error_reported: + BTreeMap, (PlaceRef<'tcx, 'tcx>, DiagnosticBuilder<'cx>)>, /// This field keeps track of errors reported in the checking of uninitialized variables, /// so that we don't report seemingly duplicate errors. uninitialized_error_reported: FxHashSet>, @@ -1527,7 +1528,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'cx, 'tcx>, Span), + place_span: (PlaceRef<'tcx, 'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1593,7 +1594,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'cx, 'tcx>, Span), + place_span: (PlaceRef<'tcx, 'tcx>, Span), maybe_uninits: &BitSet, from: u32, to: u32, @@ -1632,7 +1633,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'cx, 'tcx>, Span), + place_span: (PlaceRef<'tcx, 'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1817,7 +1818,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn check_parent_of_field<'cx, 'tcx>( this: &mut MirBorrowckCtxt<'cx, 'tcx>, location: Location, - base: PlaceRef<'cx, 'tcx>, + base: PlaceRef<'tcx, 'tcx>, span: Span, flow_state: &Flows<'cx, 'tcx>, ) { diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 31bee460fa011..b66fd42d9c024 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -29,7 +29,7 @@ pub(super) struct Prefixes<'cx, 'tcx> { body: ReadOnlyBodyAndCache<'cx, 'tcx>, tcx: TyCtxt<'tcx>, kind: PrefixSet, - next: Option>, + next: Option>, } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -50,7 +50,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// terminating the iteration early based on `kind`. pub(super) fn prefixes( &self, - place_ref: PlaceRef<'cx, 'tcx>, + place_ref: PlaceRef<'tcx, 'tcx>, kind: PrefixSet, ) -> Prefixes<'cx, 'tcx> { Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx } @@ -58,7 +58,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { - type Item = PlaceRef<'cx, 'tcx>; + type Item = PlaceRef<'tcx, 'tcx>; fn next(&mut self) -> Option { let mut cursor = self.next?; From 6200f5c362172431279cd4feed4bd20beb7e2c7e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 13:09:32 -0300 Subject: [PATCH 10/34] Make PlaceRef lifetimes of uninitialized_error_reported be both 'tcx --- src/librustc_mir/borrow_check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 2d73d96ec8b6a..fb3338f998d4a 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -472,7 +472,7 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { BTreeMap, (PlaceRef<'tcx, 'tcx>, DiagnosticBuilder<'cx>)>, /// This field keeps track of errors reported in the checking of uninitialized variables, /// so that we don't report seemingly duplicate errors. - uninitialized_error_reported: FxHashSet>, + uninitialized_error_reported: FxHashSet>, /// Errors to be reported buffer errors_buffer: Vec, /// This field keeps track of all the local variables that are declared mut and are mutated. From e32ee55a365712ef2cca97c0e37a8e56efecafd2 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 14:02:11 -0300 Subject: [PATCH 11/34] Make PlaceRef lifetimes of move_path_closest_to be both 'tcx --- src/librustc_mir/borrow_check/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index fb3338f998d4a..49c499fb62dbd 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1713,8 +1713,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// static variable, as we do not track those in the MoveData. fn move_path_closest_to( &mut self, - place: PlaceRef<'_, 'tcx>, - ) -> (PlaceRef<'cx, 'tcx>, MovePathIndex) { + place: PlaceRef<'tcx, 'tcx>, + ) -> (PlaceRef<'tcx, 'tcx>, MovePathIndex) { match self.move_data.rev_lookup.find(place) { LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { (self.move_data.move_paths[mpi].place.as_ref(), mpi) From 634a167e0594330fb50bf9bd742fdafeb73ed963 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 14:06:20 -0300 Subject: [PATCH 12/34] Make PlaceRef lifetimes of move_path_for_place be both 'tcx --- src/librustc_mir/borrow_check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 49c499fb62dbd..77129a5ef9e79 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1723,7 +1723,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn move_path_for_place(&mut self, place: PlaceRef<'_, 'tcx>) -> Option { + fn move_path_for_place(&mut self, place: PlaceRef<'tcx, 'tcx>) -> Option { // If returns None, then there is no move path corresponding // to a direct owner of `place` (which means there is nothing // that borrowck tracks for its analysis). From c6f12447193d3710a38ad2e069605fe1cc2847ba Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 17:00:15 -0300 Subject: [PATCH 13/34] Make PlaceRef lifetimes of is_upvar_field_projection be both 'tcx --- .../borrow_check/diagnostics/conflict_errors.rs | 4 ++-- src/librustc_mir/borrow_check/diagnostics/mod.rs | 6 +++--- src/librustc_mir/borrow_check/mod.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 9d609411a54bb..3a74353605294 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -51,7 +51,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - (moved_place, used_place, span): (PlaceRef<'cx, 'tcx>, PlaceRef<'tcx, 'tcx>, Span), + (moved_place, used_place, span): (PlaceRef<'tcx, 'tcx>, PlaceRef<'tcx, 'tcx>, Span), mpi: MovePathIndex, ) { debug!( @@ -647,7 +647,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // borrowed place and look for a access to a different field of the same union. let Place { local, projection } = second_borrowed_place; - let mut cursor = projection.as_ref(); + let mut cursor = &projection[..]; while let [proj_base @ .., elem] = cursor { cursor = proj_base; diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index cd6834a5a4d00..01c022ac2c10f 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -139,7 +139,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// End-user visible description of `place` if one can be found. If the /// place is a temporary for instance, None will be returned. - pub(super) fn describe_place(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Option { + pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx, 'tcx>) -> Option { self.describe_place_with_options(place_ref, IncludingDowncast(false)) } @@ -149,7 +149,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// `Downcast` and `IncludingDowncast` is true pub(super) fn describe_place_with_options( &self, - place: PlaceRef<'cx, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, including_downcast: IncludingDowncast, ) -> Option { let mut buf = String::new(); @@ -162,7 +162,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Appends end-user visible description of `place` to `buf`. fn append_place_to_string( &self, - place: PlaceRef<'cx, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, buf: &mut String, mut autoderef: bool, including_downcast: &IncludingDowncast, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 77129a5ef9e79..89a81945a27b3 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -2220,7 +2220,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. - pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Option { + pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx, 'tcx>) -> Option { let mut place_projection = place_ref.projection; let mut by_ref = false; From 6f236504570de4210eeae6e883cf8ed6196e0d98 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 17:12:31 -0300 Subject: [PATCH 14/34] Make PlaceRef lifetimes of add_moved_or_invoked_closure_note be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 01c022ac2c10f..ed95c0419e9bd 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -51,7 +51,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(super) fn add_moved_or_invoked_closure_note( &self, location: Location, - place: PlaceRef<'cx, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, diag: &mut DiagnosticBuilder<'_>, ) { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); From eb67eca74af8765dc4f5579655783b51f0270b49 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 17:22:28 -0300 Subject: [PATCH 15/34] Make PlaceRef lifetimes of describe_field be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index ed95c0419e9bd..2f054b8dd52d7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -303,7 +303,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// End-user visible description of the `field`nth field of `base` - fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { + fn describe_field(&self, place: PlaceRef<'tcx, 'tcx>, field: Field) -> String { // FIXME Place2 Make this work iteratively match place { PlaceRef { local, projection: [] } => { From a30f55f4b2fc71acd04f5649678ca09c1523096d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 17:47:00 -0300 Subject: [PATCH 16/34] Make PlaceRef lifetimes of borrowed_content_source be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/mod.rs | 2 +- src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 2f054b8dd52d7..e2d59ed3c6e87 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -399,7 +399,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(super) fn borrowed_content_source( &self, - deref_base: PlaceRef<'cx, 'tcx>, + deref_base: PlaceRef<'tcx, 'tcx>, ) -> BorrowedContentSource<'tcx> { let tcx = self.infcx.tcx; diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index d91f6edc9800c..aa35c407b64e6 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -23,7 +23,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { &mut self, access_place: &Place<'tcx>, span: Span, - the_place_err: PlaceRef<'cx, 'tcx>, + the_place_err: PlaceRef<'tcx, 'tcx>, error_access: AccessKind, location: Location, ) { From bd4dad4281220325dc5ae3ecca8c286ecba9b681 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:05:37 -0300 Subject: [PATCH 17/34] Make PlaceRef lifetimes of move_spans be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index e2d59ed3c6e87..2565eeae06bc5 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -694,7 +694,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, - moved_place: PlaceRef<'cx, 'tcx>, // Could also be an upvar. + moved_place: PlaceRef<'tcx, 'tcx>, // Could also be an upvar. location: Location, ) -> UseSpans { use self::UseSpans::*; From 46d85e519bcd2b64ca0b069055e880b425fb3e74 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:07:33 -0300 Subject: [PATCH 18/34] Make PlaceRef lifetimes of closure_span be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 2565eeae06bc5..4b1c0b05817de 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -782,7 +782,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn closure_span( &self, def_id: DefId, - target_place: PlaceRef<'cx, 'tcx>, + target_place: PlaceRef<'tcx, 'tcx>, places: &Vec>, ) -> Option<(Span, Option, Span)> { debug!( From a32afa33c8a8ad58607bafbfb9399b2c51495e61 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:10:01 -0300 Subject: [PATCH 19/34] Make PlaceRef lifetimes of classify_drop_access_kind be both 'tcx --- src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 3a74353605294..99cbc76efab88 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1521,7 +1521,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.buffer(&mut self.errors_buffer); } - fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOrDrop<'tcx> { + fn classify_drop_access_kind(&self, place: PlaceRef<'tcx, 'tcx>) -> StorageDeadOrDrop<'tcx> { let tcx = self.infcx.tcx; match place.projection { [] => StorageDeadOrDrop::LocalStorageDead, From a5d1e189a12433d61ded6da47df76929cf8e94c1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:13:47 -0300 Subject: [PATCH 20/34] Make PlaceRef lifetimes of is_prefix_of be both 'tcx --- src/librustc_mir/borrow_check/prefixes.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index b66fd42d9c024..25356cd17ef18 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -13,12 +13,12 @@ use rustc::mir::{Place, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; -pub trait IsPrefixOf<'cx, 'tcx> { - fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool; +pub trait IsPrefixOf<'tcx> { + fn is_prefix_of(&self, other: PlaceRef<'tcx, 'tcx>) -> bool; } -impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> { - fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool { +impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx, 'tcx> { + fn is_prefix_of(&self, other: PlaceRef<'tcx, 'tcx>) -> bool { self.local == other.local && self.projection.len() <= other.projection.len() && self.projection == &other.projection[..self.projection.len()] From 2cb2559c18c2d494710ab67324cdc73c4be7a46f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:18:15 -0300 Subject: [PATCH 21/34] Make PlaceRef lifetimes of in_projection be both 'tcx --- src/librustc_mir/dataflow/move_paths/builder.rs | 2 +- src/librustc_mir/transform/check_consts/qualifs.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 57aa5de7f7a31..fb7ae102a0f18 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -483,7 +483,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.builder.data.loc_map[self.loc].push(move_out); } - fn gather_init(&mut self, place: PlaceRef<'cx, 'tcx>, kind: InitKind) { + fn gather_init(&mut self, place: PlaceRef<'tcx, 'tcx>, kind: InitKind) { debug!("gather_init({:?}, {:?})", self.loc, place); let mut place = place; diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 215496e4d03cb..275b6e4d508f0 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -35,7 +35,7 @@ pub trait Qualif { fn in_projection_structurally( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'_, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { let base_qualif = Self::in_place( @@ -67,7 +67,7 @@ pub trait Qualif { fn in_projection( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'_, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, ) -> bool { Self::in_projection_structurally(cx, per_local, place) } @@ -75,7 +75,7 @@ pub trait Qualif { fn in_place( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'_, 'tcx>, + place: PlaceRef<'tcx, 'tcx>, ) -> bool { match place { PlaceRef { local, projection: [] } => per_local(local), From b11cd0b587cc2a663ef358089a2d1cf709170371 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 4 Mar 2020 18:25:03 -0300 Subject: [PATCH 22/34] PlaceRef<'a, 'tcx> -> PlaceRef<'tcx> --- src/librustc/mir/mod.rs | 8 +++--- src/librustc_codegen_ssa/mir/analyze.rs | 2 +- src/librustc_codegen_ssa/mir/operand.rs | 4 +-- src/librustc_codegen_ssa/mir/place.rs | 4 +-- .../diagnostics/conflict_errors.rs | 4 +-- .../borrow_check/diagnostics/mod.rs | 16 ++++++------ .../diagnostics/mutability_errors.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 26 ++++++++----------- .../borrow_check/places_conflict.rs | 4 +-- src/librustc_mir/borrow_check/prefixes.rs | 12 ++++----- .../dataflow/move_paths/builder.rs | 2 +- src/librustc_mir/dataflow/move_paths/mod.rs | 2 +- src/librustc_mir/transform/add_retag.rs | 2 +- .../transform/check_consts/qualifs.rs | 6 ++--- src/librustc_mir/transform/promote_consts.rs | 2 +- 15 files changed, 46 insertions(+), 50 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0d429d8879bac..ca97366f5146a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1827,9 +1827,9 @@ rustc_index::newtype_index! { } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PlaceRef<'a, 'tcx> { +pub struct PlaceRef<'tcx> { pub local: Local, - pub projection: &'a [PlaceElem<'tcx>], + pub projection: &'tcx [PlaceElem<'tcx>], } impl<'tcx> Place<'tcx> { @@ -1864,7 +1864,7 @@ impl<'tcx> Place<'tcx> { self.as_ref().as_local() } - pub fn as_ref(&self) -> PlaceRef<'tcx, 'tcx> { + pub fn as_ref(&self) -> PlaceRef<'tcx> { PlaceRef { local: self.local, projection: &self.projection } } } @@ -1875,7 +1875,7 @@ impl From for Place<'_> { } } -impl<'a, 'tcx> PlaceRef<'a, 'tcx> { +impl<'tcx> PlaceRef<'tcx> { /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or /// a single deref of a local. // diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 6214aa84b81d6..2f7e70901f0f3 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -97,7 +97,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { fn process_place( &mut self, - place_ref: &mir::PlaceRef<'tcx, 'tcx>, + place_ref: &mir::PlaceRef<'tcx>, context: PlaceContext, location: Location, ) { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 96c1351de410c..1e1fede2588df 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -364,7 +364,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn maybe_codegen_consume_direct( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'tcx, 'tcx>, + place_ref: mir::PlaceRef<'tcx>, ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); @@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_consume( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'tcx, 'tcx>, + place_ref: mir::PlaceRef<'tcx>, ) -> OperandRef<'tcx, Bx::Value> { debug!("codegen_consume(place_ref={:?})", place_ref); diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 3ff0c8dd2aa46..2eba88c6b5f31 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_place( &mut self, bx: &mut Bx, - place_ref: mir::PlaceRef<'tcx, 'tcx>, + place_ref: mir::PlaceRef<'tcx>, ) -> PlaceRef<'tcx, Bx::Value> { debug!("codegen_place(place_ref={:?})", place_ref); let cx = self.cx; @@ -497,7 +497,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { result } - pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx, 'tcx>) -> Ty<'tcx> { + pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); let place_ty = mir::Place::ty_from(place_ref.local, place_ref.projection, *self.mir, tcx); self.monomorphize(&place_ty.ty) diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 99cbc76efab88..6dc5d62babda6 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -51,7 +51,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - (moved_place, used_place, span): (PlaceRef<'tcx, 'tcx>, PlaceRef<'tcx, 'tcx>, Span), + (moved_place, used_place, span): (PlaceRef<'tcx>, PlaceRef<'tcx>, Span), mpi: MovePathIndex, ) { debug!( @@ -1521,7 +1521,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.buffer(&mut self.errors_buffer); } - fn classify_drop_access_kind(&self, place: PlaceRef<'tcx, 'tcx>) -> StorageDeadOrDrop<'tcx> { + fn classify_drop_access_kind(&self, place: PlaceRef<'tcx>) -> StorageDeadOrDrop<'tcx> { let tcx = self.infcx.tcx; match place.projection { [] => StorageDeadOrDrop::LocalStorageDead, diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 4b1c0b05817de..912b5f11f1a04 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -51,7 +51,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(super) fn add_moved_or_invoked_closure_note( &self, location: Location, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, diag: &mut DiagnosticBuilder<'_>, ) { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); @@ -139,7 +139,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// End-user visible description of `place` if one can be found. If the /// place is a temporary for instance, None will be returned. - pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx, 'tcx>) -> Option { + pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option { self.describe_place_with_options(place_ref, IncludingDowncast(false)) } @@ -149,7 +149,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// `Downcast` and `IncludingDowncast` is true pub(super) fn describe_place_with_options( &self, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, including_downcast: IncludingDowncast, ) -> Option { let mut buf = String::new(); @@ -162,7 +162,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Appends end-user visible description of `place` to `buf`. fn append_place_to_string( &self, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, buf: &mut String, mut autoderef: bool, including_downcast: &IncludingDowncast, @@ -303,7 +303,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// End-user visible description of the `field`nth field of `base` - fn describe_field(&self, place: PlaceRef<'tcx, 'tcx>, field: Field) -> String { + fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String { // FIXME Place2 Make this work iteratively match place { PlaceRef { local, projection: [] } => { @@ -399,7 +399,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(super) fn borrowed_content_source( &self, - deref_base: PlaceRef<'tcx, 'tcx>, + deref_base: PlaceRef<'tcx>, ) -> BorrowedContentSource<'tcx> { let tcx = self.infcx.tcx; @@ -694,7 +694,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, - moved_place: PlaceRef<'tcx, 'tcx>, // Could also be an upvar. + moved_place: PlaceRef<'tcx>, // Could also be an upvar. location: Location, ) -> UseSpans { use self::UseSpans::*; @@ -782,7 +782,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn closure_span( &self, def_id: DefId, - target_place: PlaceRef<'tcx, 'tcx>, + target_place: PlaceRef<'tcx>, places: &Vec>, ) -> Option<(Span, Option, Span)> { debug!( diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index aa35c407b64e6..1a13ef8958576 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -23,7 +23,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { &mut self, access_place: &Place<'tcx>, span: Span, - the_place_err: PlaceRef<'tcx, 'tcx>, + the_place_err: PlaceRef<'tcx>, error_access: AccessKind, location: Location, ) { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 89a81945a27b3..4e84a4169890e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -468,11 +468,10 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - move_error_reported: - BTreeMap, (PlaceRef<'tcx, 'tcx>, DiagnosticBuilder<'cx>)>, + move_error_reported: BTreeMap, (PlaceRef<'tcx>, DiagnosticBuilder<'cx>)>, /// This field keeps track of errors reported in the checking of uninitialized variables, /// so that we don't report seemingly duplicate errors. - uninitialized_error_reported: FxHashSet>, + uninitialized_error_reported: FxHashSet>, /// Errors to be reported buffer errors_buffer: Vec, /// This field keeps track of all the local variables that are declared mut and are mutated. @@ -1528,7 +1527,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'tcx, 'tcx>, Span), + place_span: (PlaceRef<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1594,7 +1593,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'tcx, 'tcx>, Span), + place_span: (PlaceRef<'tcx>, Span), maybe_uninits: &BitSet, from: u32, to: u32, @@ -1633,7 +1632,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, desired_action: InitializationRequiringAction, - place_span: (PlaceRef<'tcx, 'tcx>, Span), + place_span: (PlaceRef<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1711,10 +1710,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// An Err result includes a tag indicated why the search failed. /// Currently this can only occur if the place is built off of a /// static variable, as we do not track those in the MoveData. - fn move_path_closest_to( - &mut self, - place: PlaceRef<'tcx, 'tcx>, - ) -> (PlaceRef<'tcx, 'tcx>, MovePathIndex) { + fn move_path_closest_to(&mut self, place: PlaceRef<'tcx>) -> (PlaceRef<'tcx>, MovePathIndex) { match self.move_data.rev_lookup.find(place) { LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { (self.move_data.move_paths[mpi].place.as_ref(), mpi) @@ -1723,7 +1719,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn move_path_for_place(&mut self, place: PlaceRef<'tcx, 'tcx>) -> Option { + fn move_path_for_place(&mut self, place: PlaceRef<'tcx>) -> Option { // If returns None, then there is no move path corresponding // to a direct owner of `place` (which means there is nothing // that borrowck tracks for its analysis). @@ -1818,7 +1814,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn check_parent_of_field<'cx, 'tcx>( this: &mut MirBorrowckCtxt<'cx, 'tcx>, location: Location, - base: PlaceRef<'tcx, 'tcx>, + base: PlaceRef<'tcx>, span: Span, flow_state: &Flows<'cx, 'tcx>, ) { @@ -2067,9 +2063,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Returns the root place if the place passed in is a projection. fn is_mutable( &self, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, is_local_mutation_allowed: LocalMutationIsAllowed, - ) -> Result, PlaceRef<'tcx, 'tcx>> { + ) -> Result, PlaceRef<'tcx>> { match place { PlaceRef { local, projection: [] } => { let local = &self.body.local_decls[local]; @@ -2220,7 +2216,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. - pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx, 'tcx>) -> Option { + pub fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option { let mut place_projection = place_ref.projection; let mut by_ref = false; diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 1f90b94cfcdc3..767ffa50fedb4 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -48,7 +48,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, - access_place: PlaceRef<'tcx, 'tcx>, + access_place: PlaceRef<'tcx>, access: AccessDepth, bias: PlaceConflictBias, ) -> bool { @@ -73,7 +73,7 @@ fn place_components_conflict<'tcx>( body: &Body<'tcx>, borrow_place: &Place<'tcx>, borrow_kind: BorrowKind, - access_place: PlaceRef<'tcx, 'tcx>, + access_place: PlaceRef<'tcx>, access: AccessDepth, bias: PlaceConflictBias, ) -> bool { diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 25356cd17ef18..c64e8c363af54 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -14,11 +14,11 @@ use rustc::ty::{self, TyCtxt}; use rustc_hir as hir; pub trait IsPrefixOf<'tcx> { - fn is_prefix_of(&self, other: PlaceRef<'tcx, 'tcx>) -> bool; + fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool; } -impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx, 'tcx> { - fn is_prefix_of(&self, other: PlaceRef<'tcx, 'tcx>) -> bool { +impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> { + fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool { self.local == other.local && self.projection.len() <= other.projection.len() && self.projection == &other.projection[..self.projection.len()] @@ -29,7 +29,7 @@ pub(super) struct Prefixes<'cx, 'tcx> { body: ReadOnlyBodyAndCache<'cx, 'tcx>, tcx: TyCtxt<'tcx>, kind: PrefixSet, - next: Option>, + next: Option>, } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -50,7 +50,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// terminating the iteration early based on `kind`. pub(super) fn prefixes( &self, - place_ref: PlaceRef<'tcx, 'tcx>, + place_ref: PlaceRef<'tcx>, kind: PrefixSet, ) -> Prefixes<'cx, 'tcx> { Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx } @@ -58,7 +58,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> { - type Item = PlaceRef<'tcx, 'tcx>; + type Item = PlaceRef<'tcx>; fn next(&mut self) -> Option { let mut cursor = self.next?; diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index fb7ae102a0f18..0272e0c3a872a 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -483,7 +483,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.builder.data.loc_map[self.loc].push(move_out); } - fn gather_init(&mut self, place: PlaceRef<'tcx, 'tcx>, kind: InitKind) { + fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) { debug!("gather_init({:?}, {:?})", self.loc, place); let mut place = place; diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 6f6ba7dc27128..593952bfa7c80 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -312,7 +312,7 @@ impl MovePathLookup { // alternative will *not* create a MovePath on the fly for an // unknown place, but will rather return the nearest available // parent. - pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult { + pub fn find(&self, place: PlaceRef<'_>) -> LookupResult { let mut result = self.locals[place.local]; for elem in place.projection.iter() { diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index a5b467c1e101f..a12d6e02a80b1 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -14,7 +14,7 @@ pub struct AddRetag; /// after the assignment, we can be sure to obtain the same place value. /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic /// copies. Data races are UB.) -fn is_stable(place: PlaceRef<'_, '_>) -> bool { +fn is_stable(place: PlaceRef<'_>) -> bool { place.projection.iter().all(|elem| { match elem { // Which place this evaluates to can change with any memory write, diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 275b6e4d508f0..baff8383c20a4 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -35,7 +35,7 @@ pub trait Qualif { fn in_projection_structurally( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { let base_qualif = Self::in_place( @@ -67,7 +67,7 @@ pub trait Qualif { fn in_projection( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, ) -> bool { Self::in_projection_structurally(cx, per_local, place) } @@ -75,7 +75,7 @@ pub trait Qualif { fn in_place( cx: &ConstCx<'_, 'tcx>, per_local: &mut impl FnMut(Local) -> bool, - place: PlaceRef<'tcx, 'tcx>, + place: PlaceRef<'tcx>, ) -> bool { match place { PlaceRef { local, projection: [] } => per_local(local), diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 286740f99dde6..33f4e126f1efd 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -474,7 +474,7 @@ impl<'tcx> Validator<'_, 'tcx> { } } - fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> { + fn validate_place(&self, place: PlaceRef<'tcx>) -> Result<(), Unpromotable> { match place { PlaceRef { local, projection: [] } => self.validate_local(local), PlaceRef { local: _, projection: [proj_base @ .., elem] } => { From c1df945a610bb6eddfe0dc5ff033722fa611ef09 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 3 Mar 2020 01:06:07 +0300 Subject: [PATCH 23/34] rustc_metadata: Give decoder access to whole crate store --- src/librustc_metadata/creader.rs | 24 ++++++++++-- src/librustc_metadata/rmeta/decoder.rs | 39 +++++++++++-------- .../rmeta/decoder/cstore_impl.rs | 2 +- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 5254471051ffd..18b4c9ad5044c 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -76,6 +76,21 @@ impl<'a> LoadError<'a> { } } +/// A reference to `CrateMetadata` that can also give access to whole crate store when necessary. +#[derive(Clone, Copy)] +crate struct CrateMetadataRef<'a> { + pub cdata: &'a CrateMetadata, + pub cstore: &'a CStore, +} + +impl std::ops::Deref for CrateMetadataRef<'_> { + type Target = CrateMetadata; + + fn deref(&self) -> &Self::Target { + self.cdata + } +} + fn dump_crates(cstore: &CStore) { info!("resolved crates:"); cstore.iter_crate_data(|cnum, data| { @@ -100,10 +115,11 @@ impl CStore { CrateNum::new(self.metas.len() - 1) } - crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { - self.metas[cnum] + crate fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> { + let cdata = self.metas[cnum] .as_ref() - .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) + .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)); + CrateMetadataRef { cdata, cstore: self } } fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { @@ -217,7 +233,7 @@ impl<'a> CrateLoader<'a> { // We're also sure to compare *paths*, not actual byte slices. The // `source` stores paths which are normalized which may be different // from the strings on the command line. - let source = self.cstore.get_crate_data(cnum).source(); + let source = self.cstore.get_crate_data(cnum).cdata.source(); if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) { // Only use `--extern crate_name=path` here, not `--extern crate_name`. if let Some(mut files) = entry.files() { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index a72ee0cbe4729..5dec7bfe60cbd 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1,5 +1,6 @@ // Decoding metadata from a single crate's metadata +use crate::creader::CrateMetadataRef; use crate::rmeta::table::{FixedSizeEncoding, Table}; use crate::rmeta::*; @@ -125,7 +126,7 @@ struct ImportedSourceFile { pub(super) struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, - cdata: Option<&'a CrateMetadata>, + cdata: Option>, sess: Option<&'tcx Session>, tcx: Option>, @@ -141,7 +142,7 @@ pub(super) struct DecodeContext<'a, 'tcx> { /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { fn raw_bytes(self) -> &'a [u8]; - fn cdata(self) -> Option<&'a CrateMetadata> { + fn cdata(self) -> Option> { None } fn sess(self) -> Option<&'tcx Session> { @@ -162,7 +163,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { lazy_state: LazyState::NoNode, alloc_decoding_session: self .cdata() - .map(|cdata| cdata.alloc_decoding_state.new_decoding_session()), + .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()), } } } @@ -185,33 +186,33 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) { } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata { +impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadataRef<'a> { fn raw_bytes(self) -> &'a [u8] { self.blob.raw_bytes() } - fn cdata(self) -> Option<&'a CrateMetadata> { - Some(self) + fn cdata(self) -> Option> { + Some(*self) } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, &'tcx Session) { +impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) { fn raw_bytes(self) -> &'a [u8] { self.0.raw_bytes() } - fn cdata(self) -> Option<&'a CrateMetadata> { - Some(self.0) + fn cdata(self) -> Option> { + Some(*self.0) } fn sess(self) -> Option<&'tcx Session> { Some(&self.1) } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) { +impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) { fn raw_bytes(self) -> &'a [u8] { self.0.raw_bytes() } - fn cdata(self) -> Option<&'a CrateMetadata> { - Some(self.0) + fn cdata(self) -> Option> { + Some(*self.0) } fn tcx(self) -> Option> { Some(self.1) @@ -242,7 +243,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.tcx.expect("missing TyCtxt in DecodeContext") } - fn cdata(&self) -> &'a CrateMetadata { + fn cdata(&self) -> CrateMetadataRef<'a> { self.cdata.expect("missing CrateMetadata in DecodeContext") } @@ -558,7 +559,7 @@ impl CrateRoot<'_> { } } -impl<'a, 'tcx> CrateMetadata { +impl CrateMetadata { crate fn new( sess: &Session, blob: MetadataBlob, @@ -601,7 +602,9 @@ impl<'a, 'tcx> CrateMetadata { extern_crate: Lock::new(None), } } +} +impl<'a, 'tcx> CrateMetadataRef<'a> { fn is_proc_macro(&self, id: DefIndex) -> bool { self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some() } @@ -1440,10 +1443,10 @@ impl<'a, 'tcx> CrateMetadata { /// Proc macro crates don't currently export spans, so this function does not have /// to work for them. fn imported_source_files( - &'a self, + &self, local_source_map: &source_map::SourceMap, - ) -> &[ImportedSourceFile] { - self.source_map_import_info.init_locking(|| { + ) -> &'a [ImportedSourceFile] { + self.cdata.source_map_import_info.init_locking(|| { let external_source_map = self.root.source_map.decode(self); external_source_map @@ -1540,7 +1543,9 @@ impl<'a, 'tcx> CrateMetadata { dep_node_index } +} +impl CrateMetadata { crate fn dependencies(&self) -> LockGuard<'_, Vec> { self.dependencies.borrow() } diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index be229350f3bcc..c890640d432a7 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -517,7 +517,7 @@ impl CrateStore for CStore { } fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable { - &self.get_crate_data(cnum).def_path_table + &self.get_crate_data(cnum).cdata.def_path_table } fn crates_untracked(&self) -> Vec { From 41374d748b3c8bc39a78adf703d7d5560a4a8ab7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 3 Mar 2020 22:56:27 +0300 Subject: [PATCH 24/34] rustc_metadata: Move some code from `impl CrateMetadataRef` to `impl CrateMetadata` --- src/librustc_metadata/rmeta/decoder.rs | 176 ++++++++++++------------- 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 5dec7bfe60cbd..e60ae5b6c25ee 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -559,51 +559,6 @@ impl CrateRoot<'_> { } } -impl CrateMetadata { - crate fn new( - sess: &Session, - blob: MetadataBlob, - root: CrateRoot<'static>, - raw_proc_macros: Option<&'static [ProcMacro]>, - cnum: CrateNum, - cnum_map: CrateNumMap, - dep_kind: DepKind, - source: CrateSource, - private_dep: bool, - host_hash: Option, - ) -> CrateMetadata { - let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || { - root.def_path_table.decode((&blob, sess)) - }); - let trait_impls = root - .impls - .decode((&blob, sess)) - .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) - .collect(); - let alloc_decoding_state = - AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); - let dependencies = Lock::new(cnum_map.iter().cloned().collect()); - CrateMetadata { - blob, - root, - def_path_table, - trait_impls, - raw_proc_macros, - source_map_import_info: Once::new(), - alloc_decoding_state, - dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), - cnum, - cnum_map, - dependencies, - dep_kind: Lock::new(dep_kind), - source, - private_dep, - host_hash, - extern_crate: Lock::new(None), - } - } -} - impl<'a, 'tcx> CrateMetadataRef<'a> { fn is_proc_macro(&self, id: DefIndex) -> bool { self.root.proc_macro_data.and_then(|data| data.decode(self).find(|x| *x == id)).is_some() @@ -625,10 +580,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } - fn local_def_id(&self, index: DefIndex) -> DefId { - DefId { krate: self.cnum, index } - } - fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro { // DefIndex's in root.proc_macro_data have a one-to-one correspondence // with items in 'raw_proc_macros'. @@ -1194,18 +1145,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect() } - // Translate a DefId from the current compilation environment to a DefId - // for an external crate. - fn reverse_translate_def_id(&self, did: DefId) -> Option { - for (local, &global) in self.cnum_map.iter_enumerated() { - if global == did.krate { - return Some(DefId { krate: local, index: did.index }); - } - } - - None - } - fn get_inherent_implementations_for_type( &self, tcx: TyCtxt<'tcx>, @@ -1412,11 +1351,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { DefPath::make(self.cnum, id, |parent| self.def_key(parent)) } - #[inline] - fn def_path_hash(&self, index: DefIndex) -> DefPathHash { - self.def_path_table.def_path_hash(index) - } - /// Imports the source_map from an external crate into the source_map of the crate /// currently being compiled (the "local crate"). /// @@ -1519,33 +1453,52 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect() }) } +} - /// Get the `DepNodeIndex` corresponding this crate. The result of this - /// method is cached in the `dep_node_index` field. - fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex { - let mut dep_node_index = self.dep_node_index.load(); - - if unlikely!(dep_node_index == DepNodeIndex::INVALID) { - // We have not cached the DepNodeIndex for this upstream crate yet, - // so use the dep-graph to find it out and cache it. - // Note that multiple threads can enter this block concurrently. - // That is fine because the DepNodeIndex remains constant - // throughout the whole compilation session, and multiple stores - // would always write the same value. - - let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX); - let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata); - - dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node); - assert!(dep_node_index != DepNodeIndex::INVALID); - self.dep_node_index.store(dep_node_index); +impl CrateMetadata { + crate fn new( + sess: &Session, + blob: MetadataBlob, + root: CrateRoot<'static>, + raw_proc_macros: Option<&'static [ProcMacro]>, + cnum: CrateNum, + cnum_map: CrateNumMap, + dep_kind: DepKind, + source: CrateSource, + private_dep: bool, + host_hash: Option, + ) -> CrateMetadata { + let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || { + root.def_path_table.decode((&blob, sess)) + }); + let trait_impls = root + .impls + .decode((&blob, sess)) + .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) + .collect(); + let alloc_decoding_state = + AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); + let dependencies = Lock::new(cnum_map.iter().cloned().collect()); + CrateMetadata { + blob, + root, + def_path_table, + trait_impls, + raw_proc_macros, + source_map_import_info: Once::new(), + alloc_decoding_state, + dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), + cnum, + cnum_map, + dependencies, + dep_kind: Lock::new(dep_kind), + source, + private_dep, + host_hash, + extern_crate: Lock::new(None), } - - dep_node_index } -} -impl CrateMetadata { crate fn dependencies(&self) -> LockGuard<'_, Vec> { self.dependencies.borrow() } @@ -1618,6 +1571,51 @@ impl CrateMetadata { crate fn hash(&self) -> Svh { self.root.hash } + + fn local_def_id(&self, index: DefIndex) -> DefId { + DefId { krate: self.cnum, index } + } + + // Translate a DefId from the current compilation environment to a DefId + // for an external crate. + fn reverse_translate_def_id(&self, did: DefId) -> Option { + for (local, &global) in self.cnum_map.iter_enumerated() { + if global == did.krate { + return Some(DefId { krate: local, index: did.index }); + } + } + + None + } + + #[inline] + fn def_path_hash(&self, index: DefIndex) -> DefPathHash { + self.def_path_table.def_path_hash(index) + } + + /// Get the `DepNodeIndex` corresponding this crate. The result of this + /// method is cached in the `dep_node_index` field. + fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex { + let mut dep_node_index = self.dep_node_index.load(); + + if unlikely!(dep_node_index == DepNodeIndex::INVALID) { + // We have not cached the DepNodeIndex for this upstream crate yet, + // so use the dep-graph to find it out and cache it. + // Note that multiple threads can enter this block concurrently. + // That is fine because the DepNodeIndex remains constant + // throughout the whole compilation session, and multiple stores + // would always write the same value. + + let def_path_hash = self.def_path_hash(CRATE_DEF_INDEX); + let dep_node = def_path_hash.to_dep_node(dep_graph::DepKind::CrateMetadata); + + dep_node_index = tcx.dep_graph.dep_node_index_of(&dep_node); + assert!(dep_node_index != DepNodeIndex::INVALID); + self.dep_node_index.store(dep_node_index); + } + + dep_node_index + } } // Cannot be implemented on 'ProcMacro', as libproc_macro From f77afc8f9c63d789519c0b1a733462ca654d894a Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Sat, 7 Mar 2020 12:04:40 +0100 Subject: [PATCH 25/34] Allow ZSTs in `AllocRef` --- src/liballoc/alloc.rs | 34 +++++++++++++++++---- src/liballoc/raw_vec.rs | 38 +++++++++++------------- src/liballoc/raw_vec/tests.rs | 2 +- src/libcore/alloc.rs | 56 ++++++++--------------------------- src/libstd/alloc.rs | 47 ++++++++++++++++++++++------- 5 files changed, 96 insertions(+), 81 deletions(-) diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 73e8121868aba..9f82b2c6fa66d 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -165,13 +165,19 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl AllocRef for Global { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(alloc(layout)).ok_or(AllocErr).map(|p| (p, layout.size())) + fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + if layout.size() == 0 { + Ok((layout.dangling(), 0)) + } else { + unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr).map(|p| (p, layout.size())) } + } } #[inline] unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - dealloc(ptr.as_ptr(), layout) + if layout.size() != 0 { + dealloc(ptr.as_ptr(), layout) + } } #[inline] @@ -181,12 +187,28 @@ unsafe impl AllocRef for Global { layout: Layout, new_size: usize, ) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr).map(|p| (p, new_size)) + match (layout.size(), new_size) { + (0, 0) => Ok((layout.dangling(), 0)), + (0, _) => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())), + (_, 0) => { + self.dealloc(ptr, layout); + Ok((layout.dangling(), 0)) + } + (_, _) => NonNull::new(realloc(ptr.as_ptr(), layout, new_size)) + .ok_or(AllocErr) + .map(|p| (p, new_size)), + } } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr).map(|p| (p, layout.size())) + fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + if layout.size() == 0 { + Ok((layout.dangling(), 0)) + } else { + unsafe { + NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr).map(|p| (p, layout.size())) + } + } } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 345834d7daacc..b31fec7f037c9 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -73,30 +73,28 @@ impl RawVec { } fn allocate_in(mut capacity: usize, zeroed: bool, mut a: A) -> Self { - unsafe { - let elem_size = mem::size_of::(); + let elem_size = mem::size_of::(); - let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); - alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow()); + let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow()); + alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow()); - // Handles ZSTs and `capacity == 0` alike. - let ptr = if alloc_size == 0 { - NonNull::::dangling() - } else { - let align = mem::align_of::(); - let layout = Layout::from_size_align(alloc_size, align).unwrap(); - let result = if zeroed { a.alloc_zeroed(layout) } else { a.alloc(layout) }; - match result { - Ok((ptr, size)) => { - capacity = size / elem_size; - ptr.cast() - } - Err(_) => handle_alloc_error(layout), + // Handles ZSTs and `capacity == 0` alike. + let ptr = if alloc_size == 0 { + NonNull::::dangling() + } else { + let align = mem::align_of::(); + let layout = Layout::from_size_align(alloc_size, align).unwrap(); + let result = if zeroed { a.alloc_zeroed(layout) } else { a.alloc(layout) }; + match result { + Ok((ptr, size)) => { + capacity = size / elem_size; + ptr.cast() } - }; + Err(_) => handle_alloc_error(layout), + } + }; - RawVec { ptr: ptr.into(), cap: capacity, a } - } + RawVec { ptr: ptr.into(), cap: capacity, a } } } diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs index 860058debe1fd..21a8a76d0a75b 100644 --- a/src/liballoc/raw_vec/tests.rs +++ b/src/liballoc/raw_vec/tests.rs @@ -20,7 +20,7 @@ fn allocator_param() { fuel: usize, } unsafe impl AllocRef for BoundedAlloc { - unsafe fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { let size = layout.size(); if size > self.fuel { return Err(AllocErr); diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index 0a7a8ab266aee..d2a513451ccb6 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -606,20 +606,11 @@ pub unsafe trait GlobalAlloc { /// method (`dealloc`) or by being passed to a reallocation method /// (see above) that returns `Ok`. /// -/// A note regarding zero-sized types and zero-sized layouts: many -/// methods in the `AllocRef` trait state that allocation requests -/// must be non-zero size, or else undefined behavior can result. -/// -/// * If an `AllocRef` implementation chooses to return `Ok` in this -/// case (i.e., the pointer denotes a zero-sized inaccessible block) -/// then that returned pointer must be considered "currently -/// allocated". On such an allocator, *all* methods that take -/// currently-allocated pointers as inputs must accept these -/// zero-sized pointers, *without* causing undefined behavior. -/// -/// * In other words, if a zero-sized pointer can flow out of an -/// allocator, then that allocator must likewise accept that pointer -/// flowing back into its deallocation and reallocation methods. +/// Unlike [`GlobalAlloc`], zero-sized allocations are allowed in +/// `AllocRef`. If an underlying allocator does not support this (like +/// jemalloc) or return a null pointer (such as `libc::malloc`), this case +/// must be caught. In this case [`Layout::dangling()`] can be used to +/// create a dangling, but aligned `NonNull`. /// /// Some of the methods require that a layout *fit* a memory block. /// What it means for a layout to "fit" a memory block means (or @@ -649,6 +640,9 @@ pub unsafe trait GlobalAlloc { /// * if an allocator does not support overallocating, it is fine to /// simply return `layout.size()` as the allocated size. /// +/// [`GlobalAlloc`]: self::GlobalAlloc +/// [`Layout::dangling()`]: self::Layout::dangling +/// /// # Safety /// /// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and @@ -669,14 +663,6 @@ pub unsafe trait GlobalAlloc { /// the future. #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe trait AllocRef { - // (Note: some existing allocators have unspecified but well-defined - // behavior in response to a zero size allocation request ; - // e.g., in C, `malloc` of 0 will either return a null pointer or a - // unique pointer, but will not have arbitrary undefined - // behavior. - // However in jemalloc for example, - // `mallocx(0)` is documented as undefined behavior.) - /// On success, returns a pointer meeting the size and alignment /// guarantees of `layout` and the actual size of the allocated block, /// which must be greater than or equal to `layout.size()`. @@ -690,15 +676,6 @@ pub unsafe trait AllocRef { /// behavior, e.g., to ensure initialization to particular sets of /// bit patterns.) /// - /// # Safety - /// - /// This function is unsafe because undefined behavior can result - /// if the caller does not ensure that `layout` has non-zero size. - /// - /// (Extension subtraits might provide more specific bounds on - /// behavior, e.g., guarantee a sentinel address or a null pointer - /// in response to a zero-size allocation request.) - /// /// # Errors /// /// Returning `Err` indicates that either memory is exhausted or @@ -716,7 +693,7 @@ pub unsafe trait AllocRef { /// rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr>; + fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr>; /// Deallocate the memory referenced by `ptr`. /// @@ -738,10 +715,6 @@ pub unsafe trait AllocRef { /// Behaves like `alloc`, but also ensures that the contents /// are set to zero before being returned. /// - /// # Safety - /// - /// This function is unsafe for the same reasons that `alloc` is. - /// /// # Errors /// /// Returning `Err` indicates that either memory is exhausted or @@ -753,17 +726,17 @@ pub unsafe trait AllocRef { /// rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { let size = layout.size(); let result = self.alloc(layout); if let Ok((p, _)) = result { - ptr::write_bytes(p.as_ptr(), 0, size); + unsafe { ptr::write_bytes(p.as_ptr(), 0, size) } } result } // == METHODS FOR MEMORY REUSE == - // realloc. alloc_excess, realloc_excess + // realloc, realloc_zeroed, grow_in_place, grow_in_place_zeroed, shrink_in_place /// Returns a pointer suitable for holding data described by /// a new layout with `layout`’s alignment and a size given @@ -793,8 +766,6 @@ pub unsafe trait AllocRef { /// * `layout` must *fit* the `ptr` (see above). (The `new_size` /// argument need not fit it.) /// - /// * `new_size` must be greater than zero. - /// /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, /// must not overflow (i.e., the rounded value must be less than `usize::MAX`). /// @@ -1009,8 +980,7 @@ pub unsafe trait AllocRef { /// * `layout` must *fit* the `ptr` (see above); note the /// `new_size` argument need not fit it, /// - /// * `new_size` must not be greater than `layout.size()` - /// (and must be greater than zero), + /// * `new_size` must not be greater than `layout.size()`, /// /// # Errors /// diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 2da18e06d99bf..25f3ddcbebab6 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -133,24 +133,41 @@ pub use alloc_crate::alloc::*; #[derive(Debug, Default, Copy, Clone)] pub struct System; -// The AllocRef impl just forwards to the GlobalAlloc impl, which is in `std::sys::*::alloc`. +// The AllocRef impl checks the layout size to be non-zero and forwards to the GlobalAlloc impl, +// which is in `std::sys::*::alloc`. #[unstable(feature = "allocator_api", issue = "32838")] unsafe impl AllocRef for System { #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr).map(|p| (p, layout.size())) + fn alloc(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + if layout.size() == 0 { + Ok((layout.dangling(), 0)) + } else { + unsafe { + NonNull::new(GlobalAlloc::alloc(self, layout)) + .ok_or(AllocErr) + .map(|p| (p, layout.size())) + } + } } #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)) - .ok_or(AllocErr) - .map(|p| (p, layout.size())) + fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull, usize), AllocErr> { + if layout.size() == 0 { + Ok((layout.dangling(), 0)) + } else { + unsafe { + NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)) + .ok_or(AllocErr) + .map(|p| (p, layout.size())) + } + } } #[inline] unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) + if layout.size() != 0 { + GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) + } } #[inline] @@ -160,9 +177,17 @@ unsafe impl AllocRef for System { layout: Layout, new_size: usize, ) -> Result<(NonNull, usize), AllocErr> { - NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)) - .ok_or(AllocErr) - .map(|p| (p, new_size)) + match (layout.size(), new_size) { + (0, 0) => Ok((layout.dangling(), 0)), + (0, _) => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())), + (_, 0) => { + self.dealloc(ptr, layout); + Ok((layout.dangling(), 0)) + } + (_, _) => NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)) + .ok_or(AllocErr) + .map(|p| (p, new_size)), + } } } From d32924f89d1324386588bd23b0437cdeca1e0fc8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 9 Mar 2020 05:00:03 +0900 Subject: [PATCH 26/34] Check if output is immediate value --- src/librustc_codegen_llvm/asm.rs | 10 ++++++++-- src/test/ui/asm/issue-62046.rs | 11 +++++++++++ src/test/ui/asm/issue-62046.stderr | 11 +++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/asm/issue-62046.rs create mode 100644 src/test/ui/asm/issue-62046.stderr diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index c8f0fe8c72395..7975a70ab269c 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -29,11 +29,17 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let mut indirect_outputs = vec![]; for (i, (out, &place)) in ia.outputs.iter().zip(&outputs).enumerate() { if out.is_rw { - inputs.push(self.load_operand(place).immediate()); + let operand = self.load_operand(place); + if let OperandValue::Immediate(_) = operand.val { + inputs.push(operand.immediate()); + } ext_constraints.push(i.to_string()); } if out.is_indirect { - indirect_outputs.push(self.load_operand(place).immediate()); + let operand = self.load_operand(place); + if let OperandValue::Immediate(_) = operand.val { + indirect_outputs.push(operand.immediate()); + } } else { output_types.push(place.layout.llvm_type(self.cx())); } diff --git a/src/test/ui/asm/issue-62046.rs b/src/test/ui/asm/issue-62046.rs new file mode 100644 index 0000000000000..105dadd5fd373 --- /dev/null +++ b/src/test/ui/asm/issue-62046.rs @@ -0,0 +1,11 @@ +// build-fail +// ignore-emscripten no asm! support + +#![feature(asm)] + +fn main() { + unsafe { + asm!("nop" : "+r"("r15")); + //~^ malformed inline assembly + } +} diff --git a/src/test/ui/asm/issue-62046.stderr b/src/test/ui/asm/issue-62046.stderr new file mode 100644 index 0000000000000..a38a300548d48 --- /dev/null +++ b/src/test/ui/asm/issue-62046.stderr @@ -0,0 +1,11 @@ +error[E0668]: malformed inline assembly + --> $DIR/issue-62046.rs:8:9 + | +LL | asm!("nop" : "+r"("r15")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0668`. From c06fa0be82842b1b5c610e7d4243002305fa845f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 9 Mar 2020 09:31:15 +0100 Subject: [PATCH 27/34] clean up E0393 explanation --- src/librustc_error_codes/error_codes/E0393.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0393.md b/src/librustc_error_codes/error_codes/E0393.md index 7cce99401cf0c..3e853cf1b8a36 100644 --- a/src/librustc_error_codes/error_codes/E0393.md +++ b/src/librustc_error_codes/error_codes/E0393.md @@ -1,5 +1,6 @@ A type parameter which references `Self` in its default value was not specified. -Example of erroneous code: + +Erroneous code example: ```compile_fail,E0393 trait A {} From b974d6fc306d5847ad4b8bb48a99e6ca234cb6d1 Mon Sep 17 00:00:00 2001 From: Matthew Kuo Date: Sat, 7 Mar 2020 22:01:11 -0600 Subject: [PATCH 28/34] test(patterns): add borrowck tests for combination of pattern features Adds borrowck tests for the following features: - bindings_after_at - or_patterns - slice_patterns - box_patterns --- ...or-patterns-slice-patterns-box-patterns.rs | 224 ++++++++++++++++++ ...atterns-slice-patterns-box-patterns.stderr | 208 ++++++++++++++++ 2 files changed, 432 insertions(+) create mode 100644 src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs create mode 100644 src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr diff --git a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs new file mode 100644 index 0000000000000..b67d494866b85 --- /dev/null +++ b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs @@ -0,0 +1,224 @@ +// Tests using a combination of pattern features has the expected borrow checking behavior +#![feature(bindings_after_at)] +#![feature(or_patterns)] +#![feature(box_patterns)] + +#![feature(move_ref_pattern)] + +enum Test { + Foo, + Bar, + _Baz, +} + +// bindings_after_at + slice_patterns + +fn bindings_after_at_slice_patterns_move_binding(x: [String; 4]) { + match x { + a @ [.., _] => (), + _ => (), + }; + + &x; + //~^ ERROR borrow of moved value +} + +fn bindings_after_at_slice_patterns_borrows_binding_mut(mut x: [String; 4]) { + let r = match x { + ref mut foo @ [.., _] => Some(foo), + _ => None, + }; + + &x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_slice_mut1(mut x: [String; 4]) { + let r = match x { + ref foo @ [.., ref mut bar] => (), + //~^ ERROR cannot borrow + _ => (), + }; + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_slice_mut2(mut x: [String; 4]) { + let r = match x { + [ref foo @ .., ref bar] => Some(foo), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_both(mut x: [String; 4]) { + let r = match x { + ref foo @ [.., ref bar] => Some(foo), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +// bindings_after_at + or_patterns + +fn bindings_after_at_or_patterns_move(x: Option) { + match x { + foo @ Some(Test::Foo | Test::Bar) => (), + _ => (), + } + + &x; + //~^ ERROR borrow of moved value +} + +fn bindings_after_at_or_patterns_borrows(mut x: Option) { + let r = match x { + ref foo @ Some(Test::Foo | Test::Bar) => Some(foo), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_or_patterns_borrows_mut(mut x: Option) { + let r = match x { + ref mut foo @ Some(Test::Foo | Test::Bar) => Some(foo), + _ => None, + }; + + &x; + //~^ ERROR cannot borrow + + drop(r); +} + +// bindings_after_at + box_patterns + +fn bindings_after_at_box_patterns_borrows_both(mut x: Option>) { + let r = match x { + ref foo @ Some(box ref s) => Some(foo), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_box_patterns_borrows_mut(mut x: Option>) { + match x { + ref foo @ Some(box ref mut s) => (), + //~^ ERROR cannot borrow + _ => (), + }; +} + +// bindings_after_at + slice_patterns + or_patterns + +fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option; 4]) { + match x { + a @ [.., Some(Test::Foo | Test::Bar)] => (), + _ => (), + }; + + &x; + //~^ ERROR borrow of moved value +} + +fn bindings_after_at_slice_patterns_or_patterns_borrows_binding(mut x: [Option; 4]) { + let r = match x { + ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(a), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_borrows_slice(mut x: [Option; 4]) { + let r = match x { + ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(b), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +// bindings_after_at + slice_patterns + box_patterns + +fn bindings_after_at_slice_patterns_box_patterns_borrows(mut x: [Option>; 4]) { + let r = match x { + [_, ref a @ Some(box ref b), ..] => Some(a), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +// bindings_after_at + slice_patterns + or_patterns + box_patterns + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows( + mut x: [Option>; 4] +) { + let r = match x { + [_, ref a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows_mut( + mut x: [Option>; 4] +) { + let r = match x { + [_, ref mut a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows_binding( + mut x: [Option>; 4] +) { + let r = match x { + ref a @ [_, ref b @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &mut x; + //~^ ERROR cannot borrow + + drop(r); +} + +fn main() {} diff --git a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr new file mode 100644 index 0000000000000..35ed2763c2b08 --- /dev/null +++ b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr @@ -0,0 +1,208 @@ +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:40:9 + | +LL | ref foo @ [.., ref mut bar] => (), + | -------^^^^^^^^-----------^ + | | | + | | mutable borrow, by `bar`, occurs here + | immutable borrow, by `foo`, occurs here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:124:9 + | +LL | ref foo @ Some(box ref mut s) => (), + | -------^^^^^^^^^^^^---------^ + | | | + | | mutable borrow, by `s`, occurs here + | immutable borrow, by `foo`, occurs here + +error[E0382]: borrow of moved value: `x` + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:22:5 + | +LL | fn bindings_after_at_slice_patterns_move_binding(x: [String; 4]) { + | - move occurs because `x` has type `[std::string::String; 4]`, which does not implement the `Copy` trait +LL | match x { +LL | a @ [.., _] => (), + | ----------- value moved here +... +LL | &x; + | ^^ value borrowed here after move + +error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:32:5 + | +LL | ref mut foo @ [.., _] => Some(foo), + | --------------------- mutable borrow occurs here +... +LL | &x; + | ^^ immutable borrow occurs here +... +LL | drop(r); + | - mutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:54:5 + | +LL | [ref foo @ .., ref bar] => Some(foo), + | ------------ immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:66:5 + | +LL | ref foo @ [.., ref bar] => Some(foo), + | ----------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0382]: borrow of moved value: `x` + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:80:5 + | +LL | fn bindings_after_at_or_patterns_move(x: Option) { + | - move occurs because `x` has type `std::option::Option`, which does not implement the `Copy` trait +LL | match x { +LL | foo @ Some(Test::Foo | Test::Bar) => (), + | --------------------------------- + | | + | value moved here + | value moved here +... +LL | &x; + | ^^ value borrowed here after move + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:90:5 + | +LL | ref foo @ Some(Test::Foo | Test::Bar) => Some(foo), + | ------------------------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:102:5 + | +LL | ref mut foo @ Some(Test::Foo | Test::Bar) => Some(foo), + | ----------------------------------------- mutable borrow occurs here +... +LL | &x; + | ^^ immutable borrow occurs here +... +LL | drop(r); + | - mutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:116:5 + | +LL | ref foo @ Some(box ref s) => Some(foo), + | ------------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0382]: borrow of moved value: `x` + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:138:5 + | +LL | fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option; 4]) { + | - move occurs because `x` has type `[std::option::Option; 4]`, which does not implement the `Copy` trait +LL | match x { +LL | a @ [.., Some(Test::Foo | Test::Bar)] => (), + | ------------------------------------- + | | + | value moved here + | value moved here +... +LL | &x; + | ^^ value borrowed here after move + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:148:5 + | +LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(a), + | ------------------------------------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:160:5 + | +LL | ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(b), + | ---------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:174:5 + | +LL | [_, ref a @ Some(box ref b), ..] => Some(a), + | ----------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:190:5 + | +LL | [_, ref a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + | ------------------------------------------- immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:204:5 + | +LL | [_, ref mut a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + | ----------------------------------------------- mutable borrow occurs here +... +LL | &x; + | ^^ immutable borrow occurs here +... +LL | drop(r); + | - mutable borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:218:5 + | +LL | ref a @ [_, ref b @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + | ------------------------------------------------------------ immutable borrow occurs here +... +LL | &mut x; + | ^^^^^^ mutable borrow occurs here +... +LL | drop(r); + | - immutable borrow later used here + +error: aborting due to 17 previous errors + +Some errors have detailed explanations: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. From 67012158a379dbf58318346e87a631e7eb310bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 00:26:38 +0100 Subject: [PATCH 29/34] Move `analysis` to the query macro --- src/librustc/dep_graph/dep_node.rs | 2 -- src/librustc/query/mod.rs | 5 +++++ src/librustc/ty/query/config.rs | 9 +-------- src/librustc/ty/query/mod.rs | 7 +------ src/librustc/ty/query/plumbing.rs | 14 -------------- 5 files changed, 7 insertions(+), 30 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index eb7e2871bfcd8..05088dc419339 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -360,8 +360,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [anon] TraitSelect, [] CompileCodegenUnit(Symbol), - - [eval_always] Analysis(CrateNum), ]); pub trait RecoverKey<'tcx>: Sized { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index b7f4f432838be..daf89cab8af6d 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -60,6 +60,11 @@ rustc_queries! { cache_on_disk_if { key.is_local() } } + query analysis(key: CrateNum) -> Result<(), ErrorReported> { + eval_always + desc { "running analysis passes on this crate" } + } + /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its /// associated generics. query generics_of(key: DefId) -> &'tcx ty::Generics { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index e0e1ca374d9ae..178c2362def6e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -2,11 +2,10 @@ use crate::dep_graph::SerializedDepNodeIndex; use crate::dep_graph::{DepKind, DepNode}; use crate::ty::query::caches::QueryCache; use crate::ty::query::plumbing::CycleError; -use crate::ty::query::queries; use crate::ty::query::{Query, QueryState}; use crate::ty::TyCtxt; use rustc_data_structures::profiling::ProfileCategory; -use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_hir::def_id::DefId; use crate::ich::StableHashingContext; use rustc_data_structures::fingerprint::Fingerprint; @@ -87,9 +86,3 @@ where bug!("QueryDescription::load_from_disk() called for an unsupported query.") } } - -impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> { - fn describe(_tcx: TyCtxt<'_>, _: CrateNum) -> Cow<'static, str> { - "running analysis passes on this crate".into() - } -} diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 8614fd5cdca9a..f49c64a7b87a7 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -104,9 +104,4 @@ pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. -rustc_query_append! { [define_queries!][ <'tcx> - Other { - /// Runs analysis passes on the crate. - [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, - }, -]} +rustc_query_append! { [define_queries!][<'tcx>] } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c94909549df22..1769a925ec301 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1246,20 +1246,6 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { DepKind::CompileCodegenUnit => { bug!("force_from_dep_node: encountered {:?}", dep_node) } - - DepKind::Analysis => { - let def_id = if let Some(def_id) = dep_node.extract_def_id(tcx) { - def_id - } else { - // Return from the whole function. - return false - }; - tcx.force_query::>( - def_id.krate, - DUMMY_SP, - *dep_node - ); - } ); true From cbce21767b757b209c4d4df6792995fecf02c7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 02:20:33 +0100 Subject: [PATCH 30/34] Remove the need for `no_force` --- src/librustc/dep_graph/dep_node.rs | 42 ++++++------ src/librustc/dep_graph/mod.rs | 3 +- src/librustc/query/mod.rs | 2 +- src/librustc/ty/query/mod.rs | 105 ++++++++++++++++++++++++++++- src/librustc/ty/query/plumbing.rs | 92 +------------------------ src/librustc_macros/src/query.rs | 57 ++++++---------- 6 files changed, 148 insertions(+), 153 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 05088dc419339..bcb270ff0a64e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -362,29 +362,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] CompileCodegenUnit(Symbol), ]); -pub trait RecoverKey<'tcx>: Sized { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; -} - -impl RecoverKey<'tcx> for CrateNum { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| id.krate) - } -} - -impl RecoverKey<'tcx> for DefId { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx) - } -} - -impl RecoverKey<'tcx> for DefIndex { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| id.index) - } -} - -trait DepNodeParams<'tcx>: fmt::Debug { +pub(crate) trait DepNodeParams<'tcx>: fmt::Debug + Sized { const CAN_RECONSTRUCT_QUERY_KEY: bool; /// This method turns the parameters of a DepNodeConstructor into an opaque @@ -398,6 +376,8 @@ trait DepNodeParams<'tcx>: fmt::Debug { fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String { format!("{:?}", self) } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; } impl<'tcx, T> DepNodeParams<'tcx> for T @@ -418,6 +398,10 @@ where default fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String { format!("{:?}", *self) } + + default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option { + None + } } impl<'tcx> DepNodeParams<'tcx> for DefId { @@ -430,6 +414,10 @@ impl<'tcx> DepNodeParams<'tcx> for DefId { fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { tcx.def_path_str(*self) } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx) + } } impl<'tcx> DepNodeParams<'tcx> for DefIndex { @@ -442,6 +430,10 @@ impl<'tcx> DepNodeParams<'tcx> for DefIndex { fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { tcx.def_path_str(DefId::local(*self)) } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|id| id.index) + } } impl<'tcx> DepNodeParams<'tcx> for CrateNum { @@ -455,6 +447,10 @@ impl<'tcx> DepNodeParams<'tcx> for CrateNum { fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { tcx.crate_name(*self).to_string() } + + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { + dep_node.extract_def_id(tcx).map(|id| id.krate) + } } impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) { diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index eb377d20f5963..1fbd90743f402 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -6,7 +6,8 @@ mod query; mod safe; mod serialized; -pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, RecoverKey, WorkProductId}; +pub(crate) use self::dep_node::DepNodeParams; +pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, WorkProductId}; pub use self::graph::WorkProductFileKind; pub use self::graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct}; pub use self::prev::PreviousDepGraph; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index daf89cab8af6d..c8155005480ff 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1,4 +1,4 @@ -use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex}; +use crate::dep_graph::SerializedDepNodeIndex; use crate::mir; use crate::mir::interpret::{GlobalId, LitToConstInput}; use crate::traits; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index f49c64a7b87a7..8adb828fbebc4 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -1,4 +1,4 @@ -use crate::dep_graph::{self, DepConstructor, DepNode}; +use crate::dep_graph::{self, DepConstructor, DepNode, DepNodeParams}; use crate::hir::exports::Export; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintLevelMap; @@ -60,8 +60,8 @@ use std::sync::Arc; #[macro_use] mod plumbing; +pub use self::plumbing::CycleError; use self::plumbing::*; -pub use self::plumbing::{force_from_dep_node, CycleError}; mod stats; pub use self::stats::print_stats; @@ -105,3 +105,104 @@ pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder // as they will raise an fatal error on query cycles instead. rustc_query_append! { [define_queries!][<'tcx>] } + +/// The red/green evaluation system will try to mark a specific DepNode in the +/// dependency graph as green by recursively trying to mark the dependencies of +/// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` +/// where we don't know if it is red or green and we therefore actually have +/// to recompute its value in order to find out. Since the only piece of +/// information that we have at that point is the `DepNode` we are trying to +/// re-evaluate, we need some way to re-run a query from just that. This is what +/// `force_from_dep_node()` implements. +/// +/// In the general case, a `DepNode` consists of a `DepKind` and an opaque +/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint +/// is usually constructed by computing a stable hash of the query-key that the +/// `DepNode` corresponds to. Consequently, it is not in general possible to go +/// back from hash to query-key (since hash functions are not reversible). For +/// this reason `force_from_dep_node()` is expected to fail from time to time +/// because we just cannot find out, from the `DepNode` alone, what the +/// corresponding query-key is and therefore cannot re-run the query. +/// +/// The system deals with this case letting `try_mark_green` fail which forces +/// the root query to be re-evaluated. +/// +/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless. +/// Fortunately, we can use some contextual information that will allow us to +/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we +/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a +/// valid `DefPathHash`. Since we also always build a huge table that maps every +/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have +/// everything we need to re-run the query. +/// +/// Take the `mir_validated` query as an example. Like many other queries, it +/// just has a single parameter: the `DefId` of the item it will compute the +/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode` +/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` +/// is actually a `DefPathHash`, and can therefore just look up the corresponding +/// `DefId` in `tcx.def_path_hash_to_def_id`. +/// +/// When you implement a new query, it will likely have a corresponding new +/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As +/// a rule of thumb, if your query takes a `DefId` or `DefIndex` as sole parameter, +/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just +/// add it to the "We don't have enough information to reconstruct..." group in +/// the match below. +pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool { + use crate::dep_graph::DepKind; + + // We must avoid ever having to call `force_from_dep_node()` for a + // `DepNode::codegen_unit`: + // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we + // would always end up having to evaluate the first caller of the + // `codegen_unit` query that *is* reconstructible. This might very well be + // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just + // to re-trigger calling the `codegen_unit` query with the right key. At + // that point we would already have re-done all the work we are trying to + // avoid doing in the first place. + // The solution is simple: Just explicitly call the `codegen_unit` query for + // each CGU, right after partitioning. This way `try_mark_green` will always + // hit the cache instead of having to go through `force_from_dep_node`. + // This assertion makes sure, we actually keep applying the solution above. + debug_assert!( + dep_node.kind != DepKind::codegen_unit, + "calling force_from_dep_node() on DepKind::codegen_unit" + ); + + if !dep_node.kind.can_reconstruct_query_key() { + return false; + } + + rustc_dep_node_force!([dep_node, tcx] + // These are inputs that are expected to be pre-allocated and that + // should therefore always be red or green already. + DepKind::AllLocalTraitImpls | + DepKind::CrateMetadata | + DepKind::HirBody | + DepKind::Hir | + + // These are anonymous nodes. + DepKind::TraitSelect | + + // We don't have enough information to reconstruct the query key of + // these. + DepKind::CompileCodegenUnit => { + bug!("force_from_dep_node: encountered {:?}", dep_node) + } + ); + + false +} + +impl DepNode { + /// Check whether the query invocation corresponding to the given + /// DepNode is eligible for on-disk-caching. If so, this is method + /// will execute the query corresponding to the given DepNode. + /// Also, as a sanity check, it expects that the corresponding query + /// invocation has been marked as green already. + pub fn try_load_from_on_disk_cache<'tcx>(&self, tcx: TyCtxt<'tcx>) { + use crate::dep_graph::DepKind; + + rustc_dep_node_try_load_from_on_disk_cache!(self, tcx) + } +} diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 1769a925ec301..acf67f52dceaa 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,7 +2,7 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; +use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; use crate::ty::query::caches::QueryCache; use crate::ty::query::config::{QueryAccessors, QueryDescription}; use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryShardJobId}; @@ -720,7 +720,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[allow(dead_code)] - fn force_query + 'tcx>( + pub(super) fn force_query + 'tcx>( self, key: Q::Key, span: Span, @@ -1162,91 +1162,3 @@ macro_rules! define_provider_struct { } }; } - -/// The red/green evaluation system will try to mark a specific DepNode in the -/// dependency graph as green by recursively trying to mark the dependencies of -/// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` -/// where we don't know if it is red or green and we therefore actually have -/// to recompute its value in order to find out. Since the only piece of -/// information that we have at that point is the `DepNode` we are trying to -/// re-evaluate, we need some way to re-run a query from just that. This is what -/// `force_from_dep_node()` implements. -/// -/// In the general case, a `DepNode` consists of a `DepKind` and an opaque -/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint -/// is usually constructed by computing a stable hash of the query-key that the -/// `DepNode` corresponds to. Consequently, it is not in general possible to go -/// back from hash to query-key (since hash functions are not reversible). For -/// this reason `force_from_dep_node()` is expected to fail from time to time -/// because we just cannot find out, from the `DepNode` alone, what the -/// corresponding query-key is and therefore cannot re-run the query. -/// -/// The system deals with this case letting `try_mark_green` fail which forces -/// the root query to be re-evaluated. -/// -/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless. -/// Fortunately, we can use some contextual information that will allow us to -/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we -/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a -/// valid `DefPathHash`. Since we also always build a huge table that maps every -/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have -/// everything we need to re-run the query. -/// -/// Take the `mir_validated` query as an example. Like many other queries, it -/// just has a single parameter: the `DefId` of the item it will compute the -/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode` -/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` -/// is actually a `DefPathHash`, and can therefore just look up the corresponding -/// `DefId` in `tcx.def_path_hash_to_def_id`. -/// -/// When you implement a new query, it will likely have a corresponding new -/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As -/// a rule of thumb, if your query takes a `DefId` or `DefIndex` as sole parameter, -/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just -/// add it to the "We don't have enough information to reconstruct..." group in -/// the match below. -pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { - use crate::dep_graph::RecoverKey; - - // We must avoid ever having to call `force_from_dep_node()` for a - // `DepNode::codegen_unit`: - // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we - // would always end up having to evaluate the first caller of the - // `codegen_unit` query that *is* reconstructible. This might very well be - // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just - // to re-trigger calling the `codegen_unit` query with the right key. At - // that point we would already have re-done all the work we are trying to - // avoid doing in the first place. - // The solution is simple: Just explicitly call the `codegen_unit` query for - // each CGU, right after partitioning. This way `try_mark_green` will always - // hit the cache instead of having to go through `force_from_dep_node`. - // This assertion makes sure, we actually keep applying the solution above. - debug_assert!( - dep_node.kind != DepKind::codegen_unit, - "calling force_from_dep_node() on DepKind::codegen_unit" - ); - - if !dep_node.kind.can_reconstruct_query_key() { - return false; - } - - rustc_dep_node_force!([dep_node, tcx] - // These are inputs that are expected to be pre-allocated and that - // should therefore always be red or green already. - DepKind::AllLocalTraitImpls | - DepKind::CrateMetadata | - DepKind::HirBody | - DepKind::Hir | - - // These are anonymous nodes. - DepKind::TraitSelect | - - // We don't have enough information to reconstruct the query key of - // these. - DepKind::CompileCodegenUnit => { - bug!("force_from_dep_node: encountered {:?}", dep_node) - } - ); - - true -} diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 97b800decc59b..c23095968fb3e 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -425,7 +425,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut dep_node_def_stream = quote! {}; let mut dep_node_force_stream = quote! {}; let mut try_load_from_on_disk_cache_stream = quote! {}; - let mut no_force_queries = Vec::new(); let mut cached_queries = quote! {}; for group in groups.0 { @@ -444,19 +443,19 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { cached_queries.extend(quote! { #name, }); - } - if modifiers.cache.is_some() && !modifiers.no_force { try_load_from_on_disk_cache_stream.extend(quote! { DepKind::#name => { - debug_assert!(tcx.dep_graph - .node_color(self) - .map(|c| c.is_green()) - .unwrap_or(false)); - - let key = RecoverKey::recover(tcx, self).unwrap(); - if queries::#name::cache_on_disk(tcx, key, None) { - let _ = tcx.#name(key); + if <#arg as DepNodeParams>::CAN_RECONSTRUCT_QUERY_KEY { + debug_assert!($tcx.dep_graph + .node_color($dep_node) + .map(|c| c.is_green()) + .unwrap_or(false)); + + let key = <#arg as DepNodeParams>::recover($tcx, $dep_node).unwrap(); + if queries::#name::cache_on_disk($tcx, key, None) { + let _ = $tcx.#name(key); + } } } }); @@ -501,24 +500,21 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { [#attribute_stream] #name(#arg), }); - if modifiers.no_force { - no_force_queries.push(name.clone()); - } else { - // Add a match arm to force the query given the dep node - dep_node_force_stream.extend(quote! { - DepKind::#name => { - if let Some(key) = RecoverKey::recover($tcx, $dep_node) { + // Add a match arm to force the query given the dep node + dep_node_force_stream.extend(quote! { + DepKind::#name => { + if <#arg as DepNodeParams>::CAN_RECONSTRUCT_QUERY_KEY { + if let Some(key) = <#arg as DepNodeParams>::recover($tcx, $dep_node) { $tcx.force_query::>( key, DUMMY_SP, *$dep_node ); - } else { - return false; + return true; } } - }); - } + } + }); add_query_description_impl(&query, modifiers, &mut query_description_stream); } @@ -528,12 +524,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }); } - // Add an arm for the no force queries to panic when trying to force them - for query in no_force_queries { - dep_node_force_stream.extend(quote! { - DepKind::#query | - }); - } dep_node_force_stream.extend(quote! { DepKind::Null => { bug!("Cannot force dep node: {:?}", $dep_node) @@ -577,14 +567,9 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { #query_description_stream - impl DepNode { - /// Check whether the query invocation corresponding to the given - /// DepNode is eligible for on-disk-caching. If so, this is method - /// will execute the query corresponding to the given DepNode. - /// Also, as a sanity check, it expects that the corresponding query - /// invocation has been marked as green already. - pub fn try_load_from_on_disk_cache(&self, tcx: TyCtxt<'_>) { - match self.kind { + macro_rules! rustc_dep_node_try_load_from_on_disk_cache { + ($dep_node:expr, $tcx:expr) => { + match $dep_node.kind { #try_load_from_on_disk_cache_stream _ => (), } From f4450772ede7bc064d1727430acdb1b2dc851742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 02:39:18 +0100 Subject: [PATCH 31/34] Remove the `no_force` query attribute --- src/librustc/query/mod.rs | 38 -------------------------------- src/librustc_macros/src/query.rs | 16 -------------- 2 files changed, 54 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c8155005480ff..11e9acf3a3912 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -200,7 +200,6 @@ rustc_queries! { // queries). Making it anonymous avoids hashing the result, which // may save a bit of time. anon - no_force desc { "erasing regions from `{:?}`", ty } } @@ -209,7 +208,6 @@ rustc_queries! { } query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> { - no_force desc { "generating chalk-style clauses for environment" } } @@ -252,7 +250,6 @@ rustc_queries! { /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> { - no_force desc { |tcx| "computing the bounds for type parameter `{}`", { let id = tcx.hir().as_local_hir_id(key.1).unwrap(); tcx.hir().ty_param_name(id) @@ -508,7 +505,6 @@ rustc_queries! { /// form to be used outside of const eval. query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalRawResult<'tcx> { - no_force desc { |tcx| "const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id()) @@ -525,7 +521,6 @@ rustc_queries! { /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx> { - no_force desc { |tcx| "const-evaluating + checking `{}`", tcx.def_path_str(key.value.instance.def.def_id()) @@ -540,7 +535,6 @@ rustc_queries! { query const_field( key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)> ) -> ConstValue<'tcx> { - no_force desc { "extract field of const" } } @@ -549,19 +543,16 @@ rustc_queries! { query destructure_const( key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>> ) -> mir::DestructuredConst<'tcx> { - no_force desc { "destructure constant" } } query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { - no_force desc { "get a &core::panic::Location referring to a span" } } query lit_to_const( key: LitToConstInput<'tcx> ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { - no_force desc { "converting literal to const" } } } @@ -592,7 +583,6 @@ rustc_queries! { query region_scope_tree(_: DefId) -> &'tcx region::ScopeTree {} query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::BodyAndCache<'tcx> { - no_force desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } } @@ -600,7 +590,6 @@ rustc_queries! { /// given instance from the local crate. In particular, it will also /// look up the correct symbol name of instances from upstream crates. query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName { - no_force desc { "computing the symbol for `{}`", key } cache_on_disk_if { true } } @@ -647,7 +636,6 @@ rustc_queries! { Other { query vtable_methods(key: ty::PolyTraitRef<'tcx>) -> &'tcx [Option<(DefId, SubstsRef<'tcx>)>] { - no_force desc { |tcx| "finding all methods for trait {}", tcx.def_path_str(key.def_id()) } } } @@ -656,7 +644,6 @@ rustc_queries! { query codegen_fulfill_obligation( key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) ) -> Option> { - no_force cache_on_disk_if { true } desc { |tcx| "checking if `{}` fulfills its obligations", @@ -688,22 +675,18 @@ rustc_queries! { /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, /// `ty.is_copy()`, etc, since that will prune the environment where possible. query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is `Copy`", env.value } } /// Query backing `TyS::is_sized`. query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is `Sized`", env.value } } /// Query backing `TyS::is_freeze`. query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is freeze", env.value } } /// Query backing `TyS::needs_drop`. query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` needs drop", env.value } } @@ -717,7 +700,6 @@ rustc_queries! { query layout_raw( env: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Result<&'tcx ty::layout::LayoutDetails, ty::layout::LayoutError<'tcx>> { - no_force desc { "computing layout of `{}`", env.value } } } @@ -773,7 +755,6 @@ rustc_queries! { TypeChecking { query specializes(_: (DefId, DefId)) -> bool { - no_force desc { "computing whether impls specialize one another" } } query in_scope_traits_map(_: DefIndex) @@ -858,7 +839,6 @@ rustc_queries! { /// (like `Clone::clone` for example). query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option { desc { "available upstream drop-glue for `{:?}`", substs } - no_force } } @@ -903,7 +883,6 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [DefId] { - no_force desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) @@ -1070,7 +1049,6 @@ rustc_queries! { } query is_codegened_item(_: DefId) -> bool {} query codegen_unit(_: Symbol) -> Arc> { - no_force desc { "codegen_unit" } } query backend_optimization_level(_: CrateNum) -> OptLevel { @@ -1093,7 +1071,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1101,7 +1078,6 @@ rustc_queries! { query normalize_ty_after_erasing_regions( goal: ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Ty<'tcx> { - no_force desc { "normalizing `{:?}`", goal } } @@ -1111,7 +1087,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - no_force desc { "computing implied outlives bounds for `{:?}`", goal } } @@ -1122,7 +1097,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution, > { - no_force desc { "computing dropck types for `{:?}`", goal } } @@ -1131,7 +1105,6 @@ rustc_queries! { query evaluate_obligation( goal: CanonicalPredicateGoal<'tcx> ) -> Result { - no_force desc { "evaluating trait selection obligation `{}`", goal.value.value } } @@ -1142,7 +1115,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal } } @@ -1153,7 +1125,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_eq` `{:?}`", goal } } @@ -1164,7 +1135,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_subtype` `{:?}`", goal } } @@ -1175,7 +1145,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_prove_predicate` `{:?}`", goal } } @@ -1186,7 +1155,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1197,7 +1165,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1208,7 +1175,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1219,12 +1185,10 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { - no_force desc { |tcx| "testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0) @@ -1234,7 +1198,6 @@ rustc_queries! { query method_autoderef_steps( goal: CanonicalTyGoal<'tcx> ) -> MethodAutoderefStepsResult<'tcx> { - no_force desc { "computing autoderef types for `{:?}`", goal } } } @@ -1248,7 +1211,6 @@ rustc_queries! { // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning. query instance_def_size_estimate(def: ty::InstanceDef<'tcx>) -> usize { - no_force desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) } } diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index c23095968fb3e..56b7be2f7e2d5 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -51,9 +51,6 @@ enum QueryModifier { /// Don't hash the result, instead just mark a query red if it runs NoHash, - /// Don't force the query - NoForce, - /// Generate a dep node based on the dependencies of the query Anon, @@ -118,8 +115,6 @@ impl Parse for QueryModifier { Ok(QueryModifier::CycleDelayBug) } else if modifier == "no_hash" { Ok(QueryModifier::NoHash) - } else if modifier == "no_force" { - Ok(QueryModifier::NoForce) } else if modifier == "anon" { Ok(QueryModifier::Anon) } else if modifier == "eval_always" { @@ -222,9 +217,6 @@ struct QueryModifiers { /// Don't hash the result, instead just mark a query red if it runs no_hash: bool, - /// Don't force the query - no_force: bool, - /// Generate a dep node based on the dependencies of the query anon: bool, @@ -241,7 +233,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut fatal_cycle = false; let mut cycle_delay_bug = false; let mut no_hash = false; - let mut no_force = false; let mut anon = false; let mut eval_always = false; for modifier in query.modifiers.0.drain(..) { @@ -288,12 +279,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } no_hash = true; } - QueryModifier::NoForce => { - if no_force { - panic!("duplicate modifier `no_force` for query `{}`", query.name); - } - no_force = true; - } QueryModifier::Anon => { if anon { panic!("duplicate modifier `anon` for query `{}`", query.name); @@ -316,7 +301,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { fatal_cycle, cycle_delay_bug, no_hash, - no_force, anon, eval_always, } From 2f120095b59320d8c0adc3ad8f9294560bdf5c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 9 Mar 2020 14:50:09 +0100 Subject: [PATCH 32/34] Add a comment to `recover`. --- src/librustc/dep_graph/dep_node.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index bcb270ff0a64e..156f412e0902e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -377,6 +377,12 @@ pub(crate) trait DepNodeParams<'tcx>: fmt::Debug + Sized { format!("{:?}", self) } + /// This method tries to recover the query key from the given `DepNode`, + /// something which is needed when forcing `DepNode`s during red-green + /// evaluation. The query system will only call this method if + /// `CAN_RECONSTRUCT_QUERY_KEY` is `true`. + /// It is always valid to return `None` here, in which case incremental + /// compilation will treat the query as having changed instead of forcing it. fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; } From 7c60405dd63a2d5720251c97ec209d8844f56395 Mon Sep 17 00:00:00 2001 From: Dylan Nugent Date: Mon, 9 Mar 2020 12:31:33 -0400 Subject: [PATCH 33/34] Add note about localization to std::fmt docs --- src/liballoc/fmt.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index e6162e0f571e2..13ef2f063f95f 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -247,6 +247,21 @@ //! Hello, ` 123` has 3 right-aligned characters //! ``` //! +//! ## Localization +//! +//! In some programming languages, the behavior of string formatting functions +//! depends on the operating system's locale setting. The format functions +//! provided by Rust's standard library do not have any concept of locale, and +//! will produce the same results on all systems regardless of user +//! configuration. +//! +//! For example, the following code will always print `1.5` even if the system +//! locale uses a decimal separator other than a dot. +//! +//! ``` +//! println!("The value is {}", 1.5); +//! ``` +//! //! # Escaping //! //! The literal characters `{` and `}` may be included in a string by preceding From a56196205b1919bee851bdfd7e76e9b3ae5090db Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Mon, 9 Mar 2020 23:07:04 -0400 Subject: [PATCH 34/34] Vec::new is const tstable in 1.39 not 1.32 --- src/liballoc/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 61416f2b906d3..f661b83042868 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -317,7 +317,7 @@ impl Vec { /// let mut vec: Vec = Vec::new(); /// ``` #[inline] - #[rustc_const_stable(feature = "const_vec_new", since = "1.32.0")] + #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn new() -> Vec { Vec { buf: RawVec::NEW, len: 0 }