From 7d7221c250404ed468d893a642da961ef824a76b Mon Sep 17 00:00:00 2001 From: Azhng Date: Wed, 24 Jun 2020 16:33:31 -0400 Subject: [PATCH 01/16] typeck: adding type information to projection This commit modifies the Place as follow: * remove 'ty' from ProjectionKind * add type information into to Projection * replace 'ty' in Place with 'base_ty' * introduce 'ty()' in `Place` to return the final type of the `Place` * introduce `ty_before_projection()` in `Place` to return the type of a `Place` before i'th projection is applied Closes https://github.com/rust-lang/project-rfc-2229/issues/5 --- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/expr_use_visitor.rs | 4 +- src/librustc_typeck/mem_categorization.rs | 67 +++++++++++++++------ src/tools/clippy/clippy_lints/src/escape.rs | 2 +- 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index d3bccaaa3e4b9..199f49ca323e0 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { ) { if let mc::PlaceBase::Rvalue = place_with_id.place.base { if place_with_id.place.projections.is_empty() { - let typ = self.resolve_type(place_with_id.place.ty); + let typ = self.resolve_type(place_with_id.place.ty()); let body_id = self.body_id; let _ = dropck::check_drop_obligations(self, typ, span, body_id); } @@ -640,8 +640,8 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { borrow_kind: ty::BorrowKind, borrow_place: &mc::PlaceWithHirId<'tcx>, ) { - let origin = infer::DataBorrowed(borrow_place.place.ty, span); - self.type_must_outlive(origin, borrow_place.place.ty, borrow_region); + let origin = infer::DataBorrowed(borrow_place.place.ty(), span); + self.type_must_outlive(origin, borrow_place.place.ty(), borrow_region); for pointer_ty in borrow_place.place.deref_tys() { debug!( diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index b72fae96e4ca0..4e5ef4329c2c6 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -384,7 +384,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // Select just those fields of the `with` // expression that will actually be used - match with_place.place.ty.kind { + match with_place.place.ty().kind { ty::Adt(adt, substs) if adt.is_struct() => { // Consume those fields of the with expression that are needed. for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() { @@ -583,7 +583,7 @@ fn copy_or_move<'a, 'tcx>( place_with_id: &PlaceWithHirId<'tcx>, ) -> ConsumeMode { if !mc.type_is_copy_modulo_regions( - place_with_id.place.ty, + place_with_id.place.ty(), mc.tcx().hir().span(place_with_id.hir_id), ) { Move diff --git a/src/librustc_typeck/mem_categorization.rs b/src/librustc_typeck/mem_categorization.rs index d619d37be2d7b..ac42ce80689ec 100644 --- a/src/librustc_typeck/mem_categorization.rs +++ b/src/librustc_typeck/mem_categorization.rs @@ -73,18 +73,21 @@ pub enum PlaceBase { Upvar(ty::UpvarId), } -#[derive(Clone, Debug)] -pub enum ProjectionKind<'tcx> { +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ProjectionKind { /// A dereference of a pointer, reference or `Box` of the given type - Deref(Ty<'tcx>), + Deref, /// An index or a field Other, } #[derive(Clone, Debug)] pub struct Projection<'tcx> { + // Type after the projection is being applied. + ty: Ty<'tcx>, + /// Defines the type of access - kind: ProjectionKind<'tcx>, + kind: ProjectionKind, } /// A `Place` represents how a value is located in memory. @@ -92,8 +95,8 @@ pub struct Projection<'tcx> { /// This is an HIR version of `mir::Place` #[derive(Clone, Debug)] pub struct Place<'tcx> { - /// The type of the `Place` - pub ty: Ty<'tcx>, + /// The type of the `PlaceBase` + pub base_ty: Ty<'tcx>, /// The "outermost" place that holds this value. pub base: PlaceBase, /// How this place is derived from the base place. @@ -115,13 +118,13 @@ pub struct PlaceWithHirId<'tcx> { impl<'tcx> PlaceWithHirId<'tcx> { crate fn new( hir_id: hir::HirId, - ty: Ty<'tcx>, + base_ty: Ty<'tcx>, base: PlaceBase, projections: Vec>, ) -> PlaceWithHirId<'tcx> { PlaceWithHirId { hir_id: hir_id, - place: Place { ty: ty, base: base, projections: projections }, + place: Place { base_ty: base_ty, base: base, projections: projections }, } } } @@ -134,10 +137,26 @@ impl<'tcx> Place<'tcx> { /// `x: &*const u32` and the `Place` is `**x`, then the types returned are ///`*const u32` then `&*const u32`. crate fn deref_tys(&self) -> impl Iterator> + '_ { - self.projections.iter().rev().filter_map(|proj| { - if let ProjectionKind::Deref(deref_ty) = proj.kind { Some(deref_ty) } else { None } + self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| { + if ProjectionKind::Deref == proj.kind { + Some(self.ty_before_projection(index)) + } else { + None + } }) } + + // Returns the type of this `Place` after all projections have been applied. + pub fn ty(&self) -> Ty<'tcx> { + self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty) + } + + // Returns the type of this `Place` immediately before `projection_index`th projection + // is applied. + crate fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> { + assert!(projection_index < self.projections.len()); + if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty } + } } crate trait HirNode { @@ -516,8 +535,13 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { ty: Ty<'tcx>, ) -> PlaceWithHirId<'tcx> { let mut projections = base_place.place.projections; - projections.push(Projection { kind: ProjectionKind::Other }); - let ret = PlaceWithHirId::new(node.hir_id(), ty, base_place.place.base, projections); + projections.push(Projection { kind: ProjectionKind::Other, ty: ty }); + let ret = PlaceWithHirId::new( + node.hir_id(), + base_place.place.base_ty, + base_place.place.base, + projections, + ); debug!("cat_field ret {:?}", ret); ret } @@ -552,18 +576,23 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { ) -> McResult> { debug!("cat_deref: base_place={:?}", base_place); - let base_ty = base_place.place.ty; - let deref_ty = match base_ty.builtin_deref(true) { + let base_curr_ty = base_place.place.ty(); + let deref_ty = match base_curr_ty.builtin_deref(true) { Some(mt) => mt.ty, None => { - debug!("explicit deref of non-derefable type: {:?}", base_ty); + debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); return Err(()); } }; let mut projections = base_place.place.projections; - projections.push(Projection { kind: ProjectionKind::Deref(base_ty) }); - - let ret = PlaceWithHirId::new(node.hir_id(), deref_ty, base_place.place.base, projections); + projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); + + let ret = PlaceWithHirId::new( + node.hir_id(), + base_place.place.base_ty, + base_place.place.base, + projections, + ); debug!("cat_deref ret {:?}", ret); Ok(ret) } @@ -687,7 +716,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } PatKind::Slice(before, ref slice, after) => { - let element_ty = match place_with_id.place.ty.builtin_index() { + let element_ty = match place_with_id.place.ty().builtin_index() { Some(ty) => ty, None => { debug!("explicit index of non-indexable type {:?}", place_with_id); diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 59af475af175e..fcb574e437481 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -150,7 +150,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { return; } - if is_non_trait_box(cmt.place.ty) && !self.is_large_box(cmt.place.ty) { + if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) { self.set.insert(cmt.hir_id); } return; From 8dc1e42515adbf0946a235b464b2fd41619cec04 Mon Sep 17 00:00:00 2001 From: Yashhwanth Ram Date: Thu, 2 Jul 2020 11:33:37 +0530 Subject: [PATCH 02/16] libstd/net/tcp.rs: #![deny(unsafe_op_in_unsafe_fn)] Enclose unsafe operations in unsafe blocks --- src/libstd/net/tcp.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 9ac54dd5f7a65..47b8532b7a6e6 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -1,3 +1,4 @@ +#![deny(unsafe_op_in_unsafe_fn)] use crate::io::prelude::*; use crate::fmt; @@ -583,7 +584,8 @@ impl Read for TcpStream { #[inline] unsafe fn initializer(&self) -> Initializer { - Initializer::nop() + // SAFETY: Read is guaranteed to work on uninitialized memory + unsafe { Initializer::nop() } } } #[stable(feature = "rust1", since = "1.0.0")] @@ -622,7 +624,8 @@ impl Read for &TcpStream { #[inline] unsafe fn initializer(&self) -> Initializer { - Initializer::nop() + // SAFETY: Read is guaranteed to work on uninitialized memory + unsafe { Initializer::nop() } } } #[stable(feature = "rust1", since = "1.0.0")] From d5141e6829f9eeb54f3165bcd1548883713ef81c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 Mar 2020 13:48:59 +0200 Subject: [PATCH 03/16] No need to call getPageId a second time --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 62a23298c1b9f..3003ad1d56013 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2686,7 +2686,7 @@ function defocusSearchBar() { hideSidebar(); }; - autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true"); + autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true"); if (window.location.hash && window.location.hash.length > 0) { expandSection(window.location.hash.replace(/^#/, "")); From 0fcb7dabac1409f4ff51867aa5e9e0e51ec6e248 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 Mar 2020 13:59:10 +0200 Subject: [PATCH 04/16] Improve page hash handling --- src/librustdoc/html/static/main.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 3003ad1d56013..93929a67d496a 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -112,9 +112,11 @@ function defocusSearchBar() { } function getPageId() { - var id = document.location.href.split("#")[1]; - if (id) { - return id.split("?")[0].split("&")[0]; + if (window.location.hash) { + var tmp = window.location.hash.replace(/^#/, ""); + if (tmp.length > 0) { + return tmp; + } } return null; } @@ -2688,8 +2690,8 @@ function defocusSearchBar() { autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true"); - if (window.location.hash && window.location.hash.length > 0) { - expandSection(window.location.hash.replace(/^#/, "")); + if (pageId !== null) { + expandSection(pageId); } if (main) { From fc61cca41cb81af3c8167e8ceb596e2077d70310 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 Mar 2020 14:06:37 +0200 Subject: [PATCH 05/16] Expand sub code blocks block content when hidden when the page hash refers to it --- src/librustdoc/html/static/main.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 93929a67d496a..8839d4fc4e52f 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -306,6 +306,14 @@ function defocusSearchBar() { function expandSection(id) { var elem = document.getElementById(id); if (elem && isHidden(elem)) { + if (elem.tagName === "CODE" && elem.parentNode.tagName === "H4") { + // We are in a trait implementation, what we want is the parent. + elem = elem.parentNode; + if (elem.id !== null && elem.id.length > 0) { + // Change the id to the parent which is "more clear" and better for users. + window.location.hash = elem.id; + } + } var h3 = elem.parentNode.previousElementSibling; if (h3 && h3.tagName !== "H3") { h3 = h3.previousElementSibling; // skip div.docblock From cdabdfa104a3c0e7ba3ff2b37f967eb0e5000aae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Jun 2020 17:56:13 +0200 Subject: [PATCH 06/16] Simplify DOM by removing IDs for code tags --- src/librustdoc/html/render.rs | 47 ++++++------------------------ src/librustdoc/html/static/main.js | 21 +++++-------- 2 files changed, 16 insertions(+), 52 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 04c4685213b2e..dd4713d6c60f7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2586,8 +2586,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) let name = m.name.as_ref().unwrap(); 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, "

", id = id, ns_id = ns_id); + write!(w, "

", id = id); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); write!(w, ""); render_stability_since(w, m, t); @@ -2972,20 +2971,14 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct ItemType::StructField, field.name.as_ref().unwrap() )); - let ns_id = cx.derive_id(format!( - "{}.{}", - field.name.as_ref().unwrap(), - ItemType::StructField.name_space() - )); write!( w, "\ \ - {name}: {ty}\ + {name}: {ty}\ ", item_type = ItemType::StructField, id = id, - ns_id = ns_id, name = field.name.as_ref().unwrap(), ty = ty.print() ); @@ -3103,18 +3096,12 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { for variant in &e.variants { let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap())); - let ns_id = cx.derive_id(format!( - "{}.{}", - variant.name.as_ref().unwrap(), - ItemType::Variant.name_space() - )); write!( w, "
\ - \ - {name}", + \ + {name}", id = id, - ns_id = ns_id, name = variant.name.as_ref().unwrap() ); if let clean::VariantItem(ref var) = variant.inner { @@ -3155,21 +3142,13 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { variant.name.as_ref().unwrap(), field.name.as_ref().unwrap() )); - let ns_id = cx.derive_id(format!( - "{}.{}.{}.{}", - variant.name.as_ref().unwrap(), - ItemType::Variant.name_space(), - field.name.as_ref().unwrap(), - ItemType::StructField.name_space() - )); write!( w, "\ \ - {f}: {t}\ + {f}: {t}\ ", id = id, - ns_id = ns_id, f = field.name.as_ref().unwrap(), t = ty.print() ); @@ -3661,9 +3640,7 @@ fn render_impl( // 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, "", ns_id); + write!(w, "

", id, item_type, extra_class); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, ""); render_stability_since_raw(w, item.stable_since(), outer_version); @@ -3679,17 +3656,13 @@ fn render_impl( } clean::TypedefItem(ref tydef, _) => { let id = cx.derive_id(format!("{}.{}", ItemType::AssocType, name)); - let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); - write!(w, "

", id, item_type, extra_class); - write!(w, "", ns_id); + write!(w, "

", id, item_type, extra_class); assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), ""); write!(w, "

"); } clean::AssocConstItem(ref ty, ref default) => { 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, "", ns_id); + write!(w, "

", id, item_type, extra_class); assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), ""); write!(w, ""); render_stability_since_raw(w, item.stable_since(), outer_version); @@ -3704,9 +3677,7 @@ fn render_impl( } clean::AssocTypeItem(ref bounds, ref default) => { 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, "", ns_id); + write!(w, "

", id, item_type, extra_class); assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), ""); write!(w, "

"); } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8839d4fc4e52f..69e2bacc21882 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -306,14 +306,6 @@ function defocusSearchBar() { function expandSection(id) { var elem = document.getElementById(id); if (elem && isHidden(elem)) { - if (elem.tagName === "CODE" && elem.parentNode.tagName === "H4") { - // We are in a trait implementation, what we want is the parent. - elem = elem.parentNode; - if (elem.id !== null && elem.id.length > 0) { - // Change the id to the parent which is "more clear" and better for users. - window.location.hash = elem.id; - } - } var h3 = elem.parentNode.previousElementSibling; if (h3 && h3.tagName !== "H3") { h3 = h3.previousElementSibling; // skip div.docblock @@ -2561,6 +2553,13 @@ function defocusSearchBar() { onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); + var pageId = getPageId(); + + autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true"); + + if (pageId !== null) { + expandSection(pageId); + } }()); function createToggleWrapper(tog) { @@ -2696,12 +2695,6 @@ function defocusSearchBar() { hideSidebar(); }; - autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true"); - - if (pageId !== null) { - expandSection(pageId); - } - if (main) { onEachLazy(main.getElementsByClassName("loading-content"), function(e) { e.remove(); From 2453946b1d64570f52f2f976ca1e8c2a3e4eacc2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Jun 2020 18:27:03 +0200 Subject: [PATCH 07/16] Update rustdoc tests --- src/test/rustdoc/assoc-types.rs | 2 -- src/test/rustdoc/const.rs | 2 +- src/test/rustdoc/inline_cross/impl_trait.rs | 4 ++-- src/test/rustdoc/intra-link-self.rs | 2 +- src/test/rustdoc/intra-links.rs | 4 ++-- src/test/rustdoc/issue-19190.rs | 4 ++-- src/test/rustdoc/issue-25001.rs | 3 --- src/test/rustdoc/issue-35169-2.rs | 14 +++++++------- src/test/rustdoc/issue-35169.rs | 14 +++++++------- src/test/rustdoc/struct-field.rs | 2 +- 10 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/test/rustdoc/assoc-types.rs b/src/test/rustdoc/assoc-types.rs index b708dc0c717ca..5f0fdbb322cad 100644 --- a/src/test/rustdoc/assoc-types.rs +++ b/src/test/rustdoc/assoc-types.rs @@ -5,9 +5,7 @@ // @has assoc_types/trait.Index.html pub trait Index { // @has - '//*[@id="associatedtype.Output"]//code' 'type Output: ?Sized' - // @has - '//code[@id="Output.t"]' 'type Output: ?Sized' type Output: ?Sized; - // @has - '//code[@id="index.v"]' 'fn index' // @has - '//*[@id="tymethod.index"]//code' \ // "fn index<'a>(&'a self, index: I) -> &'a Self::Output" // @has - '//*[@id="tymethod.index"]//code//a[@href="../assoc_types/trait.Index.html#associatedtype.Output"]' \ diff --git a/src/test/rustdoc/const.rs b/src/test/rustdoc/const.rs index c33db5809cc7c..638de3292becb 100644 --- a/src/test/rustdoc/const.rs +++ b/src/test/rustdoc/const.rs @@ -3,7 +3,7 @@ pub struct Foo; impl Foo { - // @has const/struct.Foo.html '//code[@id="new.v"]' 'const unsafe fn new' + // @has const/struct.Foo.html '//*[@id="method.new"]//code' 'const unsafe fn new' pub const unsafe fn new() -> Foo { Foo } diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index 6f4a48c83c05b..e3a166b3d0e5f 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -31,8 +31,8 @@ pub use impl_trait_aux::func4; pub use impl_trait_aux::async_fn; // @has impl_trait/struct.Foo.html -// @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into> + 'a)" -// @!has - '//code[@id="method.v"]' 'where' +// @has - '//*[@id="method.method"]//code' "pub fn method<'a>(_x: impl Clone + Into> + 'a)" +// @!has - '//*[@id="method.method"]//code' 'where' pub use impl_trait_aux::Foo; // @has impl_trait/struct.Bar.html diff --git a/src/test/rustdoc/intra-link-self.rs b/src/test/rustdoc/intra-link-self.rs index 97752d5cfcb5c..81545fec7411b 100644 --- a/src/test/rustdoc/intra-link-self.rs +++ b/src/test/rustdoc/intra-link-self.rs @@ -40,7 +40,7 @@ pub struct MyStruct { } pub enum MyEnum { - // @has foo/enum.MyEnum.html '//a/@href' '../foo/enum.MyEnum.html#EnumVariant.v' + // @has foo/enum.MyEnum.html '//a/@href' '../foo/enum.MyEnum.html#variant.EnumVariant' /// [`EnumVariant`] /// diff --git a/src/test/rustdoc/intra-links.rs b/src/test/rustdoc/intra-links.rs index c356ab3a8ac52..c6725f526aa2a 100644 --- a/src/test/rustdoc/intra-links.rs +++ b/src/test/rustdoc/intra-links.rs @@ -2,7 +2,7 @@ // @has - '//a/@href' '../intra_links/struct.ThisType.html' // @has - '//a/@href' '../intra_links/struct.ThisType.html#method.this_method' // @has - '//a/@href' '../intra_links/enum.ThisEnum.html' -// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#ThisVariant.v' +// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#variant.ThisVariant' // @has - '//a/@href' '../intra_links/trait.ThisTrait.html' // @has - '//a/@href' '../intra_links/trait.ThisTrait.html#tymethod.this_associated_method' // @has - '//a/@href' '../intra_links/trait.ThisTrait.html#associatedtype.ThisAssociatedType' @@ -73,7 +73,7 @@ pub fn SoAmbiguous() {} // @has - '//a/@href' '../intra_links/struct.ThisType.html' // @has - '//a/@href' '../intra_links/struct.ThisType.html#method.this_method' // @has - '//a/@href' '../intra_links/enum.ThisEnum.html' -// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#ThisVariant.v' +// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#variant.ThisVariant' /// Shortcut links for: /// * [`ThisType`] /// * [`ThisType::this_method`] diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index c6bac51c5740d..af3495fec187f 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -17,7 +17,7 @@ impl Deref for Bar { // @has issue_19190/Bar.t.html // @has issue_19190/struct.Bar.html -// @has - '//*[@id="foo.v"]' 'fn foo(&self)' +// @has - '//*[@id="method.foo"]//code' 'fn foo(&self)' // @has - '//*[@id="method.foo"]' 'fn foo(&self)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' +// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-25001.rs b/src/test/rustdoc/issue-25001.rs index 55d8ee394385b..e53cf6451353f 100644 --- a/src/test/rustdoc/issue-25001.rs +++ b/src/test/rustdoc/issue-25001.rs @@ -9,17 +9,14 @@ pub trait Bar { impl Foo { // @has - '//*[@id="method.pass"]//code' 'fn pass()' - // @has - '//code[@id="pass.v"]' 'fn pass()' pub fn pass() {} } impl Foo { // @has - '//*[@id="method.pass-1"]//code' 'fn pass() -> usize' - // @has - '//code[@id="pass.v-1"]' 'fn pass() -> usize' pub fn pass() -> usize { 42 } } impl Foo { // @has - '//*[@id="method.pass-2"]//code' 'fn pass() -> isize' - // @has - '//code[@id="pass.v-2"]' 'fn pass() -> isize' pub fn pass() -> isize { 42 } } diff --git a/src/test/rustdoc/issue-35169-2.rs b/src/test/rustdoc/issue-35169-2.rs index 33f7646ced68b..a688ae48d00ce 100644 --- a/src/test/rustdoc/issue-35169-2.rs +++ b/src/test/rustdoc/issue-35169-2.rs @@ -24,17 +24,17 @@ impl DerefMut for Bar { } // @has issue_35169_2/struct.Bar.html -// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' +// @has - '//*[@id="method.by_ref"]//code' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' -// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' +// @has - '//*[@id="method.by_explicit_ref"]//code' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' -// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' +// @has - '//*[@id="method.by_mut_ref"]//code' 'fn by_mut_ref(&mut self)' // @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' -// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' +// @has - '//*[@id="method.by_explicit_mut_ref"]//code' 'fn by_explicit_mut_ref(self: &mut Foo)' // @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' -// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' +// @!has - '//*[@id="method.by_explicit_box"]//code' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' -// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' +// @!has - '//*[@id="method.by_explicit_self_box"]//code' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' +// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/issue-35169.rs b/src/test/rustdoc/issue-35169.rs index 04fffc40572a6..4f10c04a616b3 100644 --- a/src/test/rustdoc/issue-35169.rs +++ b/src/test/rustdoc/issue-35169.rs @@ -19,17 +19,17 @@ impl Deref for Bar { } // @has issue_35169/struct.Bar.html -// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)' +// @has - '//*[@id="method.by_ref"]//code' 'fn by_ref(&self)' // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)' -// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)' +// @has - '//*[@id="method.by_explicit_ref"]//code' 'fn by_explicit_ref(self: &Foo)' // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)' -// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)' +// @!has - '//*[@id="method.by_mut_ref"]//code' 'fn by_mut_ref(&mut self)' // @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)' -// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)' +// @!has - '//*[@id="method.by_explicit_mut_ref"]//code' 'fn by_explicit_mut_ref(self: &mut Foo)' // @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)' -// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box)' +// @!has - '//*[@id="method.by_explicit_box"]//code' 'fn by_explicit_box(self: Box)' // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box)' -// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box)' +// @!has - '//*[@id="method.by_explicit_self_box"]//code' 'fn by_explicit_self_box(self: Box)' // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box)' -// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()' +// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()' // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()' diff --git a/src/test/rustdoc/struct-field.rs b/src/test/rustdoc/struct-field.rs index c99169fbca57f..532e29bc691c4 100644 --- a/src/test/rustdoc/struct-field.rs +++ b/src/test/rustdoc/struct-field.rs @@ -4,7 +4,7 @@ // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar' // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo' -// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#X.v"]' 'Uniooon::X' +// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#variant.X"]' 'Uniooon::X' //! Test with [Foo::bar], [Bar::foo], [Uniooon::X] From af2962027721b8dc700de339350f96b284c15fcd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 28 Jun 2020 00:43:01 +0200 Subject: [PATCH 08/16] Fix links --- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- src/libstd/sys/unix/ext/fs.rs | 2 +- src/libstd/sys/vxworks/ext/fs.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8da74f375d9ce..0e6a6c8a5e699 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1069,7 +1069,7 @@ fn handle_variant( }; let parent_def = Res::Def(DefKind::Enum, parent); let variant = cx.tcx.expect_variant_res(res); - Ok((parent_def, Some(format!("{}.v", variant.ident.name)))) + Ok((parent_def, Some(format!("variant.{}", variant.ident.name)))) } const PRIMITIVES: &[(&str, Res)] = &[ diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index e4d714936047e..2b2bbc6e9d6ae 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -133,7 +133,7 @@ pub trait FileExt { /// Note that similar to [`File::write`], it is not an error to return a /// short write. /// - /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v + /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write /// /// # Examples /// diff --git a/src/libstd/sys/vxworks/ext/fs.rs b/src/libstd/sys/vxworks/ext/fs.rs index 7cc64658ee1a9..b479fbaf34613 100644 --- a/src/libstd/sys/vxworks/ext/fs.rs +++ b/src/libstd/sys/vxworks/ext/fs.rs @@ -132,7 +132,7 @@ pub trait FileExt { /// Note that similar to [`File::write`], it is not an error to return a /// short write. /// - /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v + /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write /// /// # Examples /// From e955bebcda257d290278b53c1677e7c54e65f134 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Jul 2020 14:14:59 +0200 Subject: [PATCH 09/16] Remove render-redirect-pages option in rustdoc --- src/bootstrap/bin/rustdoc.rs | 15 +------------ src/bootstrap/doc.rs | 1 - src/librustdoc/config.rs | 4 ---- src/librustdoc/html/item_type.rs | 37 -------------------------------- src/librustdoc/html/render.rs | 12 ----------- src/librustdoc/lib.rs | 7 ------ src/test/rustdoc/issue-19190.rs | 3 --- src/test/rustdoc/structfields.rs | 8 ------- 8 files changed, 1 insertion(+), 86 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index ba644e6111827..8c56cf1cb3414 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -13,7 +13,6 @@ fn main() { let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set"); let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); - let mut has_unstable = false; use std::str::FromStr; @@ -55,22 +54,10 @@ fn main() { cmd.arg("--crate-version").arg(version); } - // Needed to be able to run all rustdoc tests. - if env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES").is_some() { - // This "unstable-options" can be removed when `--generate-redirect-pages` is stabilized - if !has_unstable { - cmd.arg("-Z").arg("unstable-options"); - } - cmd.arg("--generate-redirect-pages"); - has_unstable = true; - } - // Needed to be able to run all rustdoc tests. if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") { // This "unstable-options" can be removed when `--resource-suffix` is stabilized - if !has_unstable { - cmd.arg("-Z").arg("unstable-options"); - } + cmd.arg("-Z").arg("unstable-options"); cmd.arg("--resource-suffix").arg(x); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 8b76158f9e564..4c6f69fdbabd8 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -451,7 +451,6 @@ impl Step for Std { .arg("--markdown-css") .arg("rust.css") .arg("--markdown-no-toc") - .arg("--generate-redirect-pages") .arg("-Z") .arg("unstable-options") .arg("--resource-suffix") diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 35b15cf717cee..14a6f3c89a3c9 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -242,8 +242,6 @@ pub struct RenderOptions { /// If false, the `select` element to have search filtering by crates on rendered docs /// won't be generated. pub generate_search_filter: bool, - /// Option (disabled by default) to generate files used by RLS and some other tools. - pub generate_redirect_pages: bool, /// Document items that have lower than `pub` visibility. pub document_private: bool, /// Document items that have `doc(hidden)`. @@ -528,7 +526,6 @@ impl Options { let static_root_path = matches.opt_str("static-root-path"); let generate_search_filter = !matches.opt_present("disable-per-crate-search"); let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from); - let generate_redirect_pages = matches.opt_present("generate-redirect-pages"); let test_builder = matches.opt_str("test-builder").map(PathBuf::from); let codegen_options_strs = matches.opt_strs("C"); let debugging_options_strs = matches.opt_strs("Z"); @@ -592,7 +589,6 @@ impl Options { markdown_css, markdown_playground_url, generate_search_filter, - generate_redirect_pages, document_private, document_hidden, }, diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index 0b2b0cdc18b09..cc78b4682d231 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -154,38 +154,6 @@ impl ItemType { ItemType::TraitAlias => "traitalias", } } - - pub fn name_space(&self) -> &'static str { - match *self { - ItemType::Struct - | ItemType::Union - | ItemType::Enum - | ItemType::Module - | ItemType::Typedef - | ItemType::Trait - | ItemType::Primitive - | ItemType::AssocType - | ItemType::OpaqueTy - | ItemType::TraitAlias - | ItemType::ForeignType => NAMESPACE_TYPE, - - ItemType::ExternCrate - | ItemType::Import - | ItemType::Function - | ItemType::Static - | ItemType::Impl - | ItemType::TyMethod - | ItemType::Method - | ItemType::StructField - | ItemType::Variant - | ItemType::Constant - | ItemType::AssocConst => NAMESPACE_VALUE, - - ItemType::Macro | ItemType::ProcAttribute | ItemType::ProcDerive => NAMESPACE_MACRO, - - ItemType::Keyword => NAMESPACE_KEYWORD, - } - } } impl fmt::Display for ItemType { @@ -193,8 +161,3 @@ impl fmt::Display for ItemType { write!(f, "{}", self.as_str()) } } - -pub const NAMESPACE_TYPE: &str = "t"; -pub const NAMESPACE_VALUE: &str = "v"; -pub const NAMESPACE_MACRO: &str = "m"; -pub const NAMESPACE_KEYWORD: &str = "k"; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index dd4713d6c60f7..69e3540ed625b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -195,8 +195,6 @@ crate struct SharedContext { /// Optional path string to be used to load static files on output pages. If not set, uses /// combinations of `../` to reach the documentation root. pub static_root_path: Option, - /// Option disabled by default to generate files used by RLS and some other tools. - pub generate_redirect_pages: bool, /// The fs handle we are working with. pub fs: DocFS, /// The default edition used to parse doctests. @@ -468,7 +466,6 @@ pub fn run( resource_suffix, static_root_path, generate_search_filter, - generate_redirect_pages, document_private, .. } = options; @@ -536,7 +533,6 @@ pub fn run( themes, resource_suffix, static_root_path, - generate_redirect_pages, fs: DocFS::new(&errors), edition, codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), @@ -1556,14 +1552,6 @@ impl Context { if !self.render_redirect_pages { all.append(full_path(self, &item), &item_type); } - if self.shared.generate_redirect_pages { - // Redirect from a sane URL using the namespace to Rustdoc's - // URL for the page. - let redir_name = format!("{}.{}.html", name, item_type.name_space()); - let redir_dst = self.dst.join(redir_name); - let v = layout::redirect(file_name); - self.shared.fs.write(&redir_dst, v.as_bytes())?; - } // If the item is a macro, redirect from the old macro URL (with !) // to the new one (without). if item_type == ItemType::Macro { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index de6fa3dbd4a89..8e2dd77cc1155 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -374,13 +374,6 @@ fn opts() -> Vec { "PATH", ) }), - unstable("generate-redirect-pages", |o| { - o.optflag( - "", - "generate-redirect-pages", - "Generate extra pages to support legacy URLs and tool links", - ) - }), unstable("show-coverage", |o| { o.optflag( "", diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs index af3495fec187f..9dac49c6413d8 100644 --- a/src/test/rustdoc/issue-19190.rs +++ b/src/test/rustdoc/issue-19190.rs @@ -1,5 +1,3 @@ -// compile-flags:-Z unstable-options --generate-redirect-pages - use std::ops::Deref; pub struct Foo; @@ -15,7 +13,6 @@ impl Deref for Bar { fn deref(&self) -> &Foo { loop {} } } -// @has issue_19190/Bar.t.html // @has issue_19190/struct.Bar.html // @has - '//*[@id="method.foo"]//code' 'fn foo(&self)' // @has - '//*[@id="method.foo"]' 'fn foo(&self)' diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs index 235f0e852da2c..6de198453cd27 100644 --- a/src/test/rustdoc/structfields.rs +++ b/src/test/rustdoc/structfields.rs @@ -1,7 +1,3 @@ -// compile-flags:-Z unstable-options --generate-redirect-pages - -// @has structfields/Foo.t.html -// @has - struct.Foo.html // @has structfields/struct.Foo.html pub struct Foo { // @has - //pre "pub a: ()" @@ -16,8 +12,6 @@ pub struct Foo { pub d: usize, } -// @has structfields/Bar.t.html -// @has - struct.Bar.html // @has structfields/struct.Bar.html pub struct Bar { // @has - //pre "pub a: ()" @@ -25,8 +19,6 @@ pub struct Bar { // @!has - //pre "// some fields omitted" } -// @has structfields/Qux.t.html -// @has - enum.Qux.html // @has structfields/enum.Qux.html pub enum Qux { Quz { From ee8dd4e3cce3bf158a31e50205ee3ebd76c40370 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 4 Jul 2020 19:30:45 +0200 Subject: [PATCH 10/16] Fix const prop ICE we used to erase the local just before we tried to read it for diagnostics --- src/librustc_mir/transform/const_prop.rs | 40 ++++++++++--------- .../const_prop/ice-assert-fail-div-by-zero.rs | 9 +++++ 2 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index e4c1ca4e851b0..fbe3377d87500 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -1004,14 +1004,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected)); let value_const = self.ecx.read_scalar(value).unwrap(); if expected != value_const { - // Poison all places this operand references so that further code - // doesn't use the invalid value - match cond { - Operand::Move(ref place) | Operand::Copy(ref place) => { - Self::remove_const(&mut self.ecx, place.local); - } - Operand::Constant(_) => {} - } let mut eval_to_int = |op| { let op = self .eval_operand(op, source_info) @@ -1020,27 +1012,37 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { }; let msg = match msg { AssertKind::DivisionByZero(op) => { - AssertKind::DivisionByZero(eval_to_int(op)) + Some(AssertKind::DivisionByZero(eval_to_int(op))) } AssertKind::RemainderByZero(op) => { - AssertKind::RemainderByZero(eval_to_int(op)) + Some(AssertKind::RemainderByZero(eval_to_int(op))) } AssertKind::BoundsCheck { ref len, ref index } => { let len = eval_to_int(len); let index = eval_to_int(index); - AssertKind::BoundsCheck { len, index } + Some(AssertKind::BoundsCheck { len, index }) } // Overflow is are already covered by checks on the binary operators. - AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => return, + AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => None, // Need proper const propagator for these. - _ => return, + _ => None, }; - self.report_assert_as_lint( - lint::builtin::UNCONDITIONAL_PANIC, - source_info, - "this operation will panic at runtime", - msg, - ); + // Poison all places this operand references so that further code + // doesn't use the invalid value + match cond { + Operand::Move(ref place) | Operand::Copy(ref place) => { + Self::remove_const(&mut self.ecx, place.local); + } + Operand::Constant(_) => {} + } + if let Some(msg) = msg { + self.report_assert_as_lint( + lint::builtin::UNCONDITIONAL_PANIC, + source_info, + "this operation will panic at runtime", + msg, + ); + } } else { if self.should_const_prop(value) { if let ScalarMaybeUninit::Scalar(scalar) = value_const { diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs new file mode 100644 index 0000000000000..5f2d5e80243fe --- /dev/null +++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs @@ -0,0 +1,9 @@ +// check-pass + +pub struct Fixed64(i64); + +pub fn div(f: Fixed64) { + f.0 / 0; +} + +fn main() {} From 2f314268b8c9ddc0ecbeeba67b036bc02e8d5f5b Mon Sep 17 00:00:00 2001 From: Kristofer Rye Date: Sun, 5 Jul 2020 11:56:41 -0500 Subject: [PATCH 11/16] rustdoc: Restore underline text decoration on hover for FQN in header This causes the components of FQN's to behave similarly to other links in the contents of rustdoc-styled pages. I (and I hope others at least in part) have found the prior design to be somewhat confusing, as it is not clear (upon hovering) that the various parts of the FQN are actually links that the user can navigate to. In short, this patch makes links in the FQN have an underline when the user hovers over them, more clearly indicating that they can be used for navigation. Signed-off-by: Kristofer Rye --- src/librustdoc/html/static/rustdoc.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 9c6dd25394db0..a3f4dc55fe757 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -100,6 +100,9 @@ h1.fqn { border-bottom: 1px dashed; margin-top: 0; } +h1.fqn > .in-band > a:hover { + text-decoration: underline; +} h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { border-bottom: 1px solid; } From 5fa19ad2bb7e6af6f05a299f2ab0120c6d2e4c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 6 Jul 2020 00:00:00 +0000 Subject: [PATCH 12/16] Remove unused RUSTC_DEBUG_ASSERTIONS Since #73374 the rustc wrapper no longer configures debug assertions based on RUSTC_DEBUG_ASSERTIONS environment variable. --- src/bootstrap/test.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 77bcc00d75b2b..312532558090e 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -397,8 +397,6 @@ impl Step for Miri { cargo.env("MIRI", &miri); // Debug things. cargo.env("RUST_BACKTRACE", "1"); - // Overwrite bootstrap's `rustc` wrapper overwriting our flags. - cargo.env("RUSTC_DEBUG_ASSERTIONS", "true"); // Let cargo-miri know where xargo ended up. cargo.env("XARGO_CHECK", builder.out.join("bin").join("xargo-check")); From f226e6bf0a97a04e57f29a3c8769c8cdc8263ebf Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 3 Jul 2020 16:20:37 -0700 Subject: [PATCH 13/16] Add `read_exact_at` and `write_all_at` to WASI's `FileExt` This adds `read_exact_at` and `write_all_at` to WASI's `FileExt`, similar to the Unix versions of the same names. --- src/libstd/sys/wasi/ext/fs.rs | 94 +++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index 6696efa8871c2..10ea4fd34bda3 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -27,6 +27,58 @@ pub trait FileExt { /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read_vectored fn read_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result; + /// Reads the exact number of byte required to fill `buf` from the given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`. + /// + /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact + /// [`read_at`]: #tymethod.read_at + /// + /// # Errors + /// + /// If this function encounters an error of the kind + /// [`ErrorKind::Interrupted`] then the error is ignored and the operation + /// will continue. + /// + /// If this function encounters an "end of file" before completely filling + /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`]. + /// The contents of `buf` are unspecified in this case. + /// + /// If any other read error is encountered then this function immediately + /// returns. The contents of `buf` are unspecified in this case. + /// + /// If this function returns an error, it is unspecified how many bytes it + /// has read, but it will never read more than would be necessary to + /// completely fill the buffer. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.read_at(buf, offset) { + Ok(0) => break, + Ok(n) => { + let tmp = buf; + buf = &mut tmp[n..]; + offset += n as u64; + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + if !buf.is_empty() { + Err(io::Error::new(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer")) + } else { + Ok(()) + } + } + /// Writes a number of bytes starting from a given offset. /// /// Returns the number of bytes written. @@ -45,6 +97,48 @@ pub trait FileExt { /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write_vectored fn write_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result; + /// Attempts to write an entire buffer starting from a given offset. + /// + /// The offset is relative to the start of the file and thus independent + /// from the current cursor. + /// + /// The current file cursor is not affected by this function. + /// + /// This method will continuously call [`write_at`] until there is no more data + /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is + /// returned. This method will not return until the entire buffer has been + /// successfully written or such an error occurs. The first error that is + /// not of [`ErrorKind::Interrupted`] kind generated from this method will be + /// returned. + /// + /// # Errors + /// + /// This function will return the first error of + /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns. + /// + /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted + /// [`write_at`]: #tymethod.write_at + #[stable(feature = "rw_exact_all_at", since = "1.33.0")] + fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + match self.write_at(buf, offset) { + Ok(0) => { + return Err(io::Error::new( + io::ErrorKind::WriteZero, + "failed to write whole buffer", + )); + } + Ok(n) => { + buf = &buf[n..]; + offset += n as u64 + } + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + Ok(()) + } + /// Returns the current position within the file. /// /// This corresponds to the `fd_tell` syscall and is similar to From 6196eaa0b1ca4e7857d8d62817aebf3b03216a57 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 3 Jul 2020 12:05:59 -0700 Subject: [PATCH 14/16] Fix the return type of Windows' `OpenOptionsExt::security_qos_flags`. This adjusts the return type of Windows' `OpenOptionsExt::security_qos_flags` to be consistent with the other functions in the trait. --- src/libstd/sys/windows/ext/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index f85120d170f73..81b2bf9987200 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -259,7 +259,7 @@ pub trait OpenOptionsExt { /// [Impersonation Levels]: /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level #[stable(feature = "open_options_ext", since = "1.10.0")] - fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions; + fn security_qos_flags(&mut self, flags: u32) -> &mut Self; } #[stable(feature = "open_options_ext", since = "1.10.0")] From e46c18768e3c0f046942b907d32b3c02c100b163 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 5 Jul 2020 21:20:31 -0400 Subject: [PATCH 15/16] Always resolve type@primitive as a primitive, not a module Previously, if there were a module in scope with the same name as the primitive, that would take precedence. Coupled with https://github.com/rust-lang/rust/issues/58699, this made it impossible to link to the primitive when that module was in scope. This approach could be extended so that `struct@foo` would no longer resolve to any type, etc. However, it could not be used for glob imports: ```rust pub mod foo { pub struct Bar; } pub enum Bar {} use foo::*; // This is expected to link to `inner::Bar`, but instead it will link to the enum. /// Link to [struct@Bar] pub struct MyDocs; ``` The reason for this is that this change does not affect the resolution algorithm of rustc_resolve at all. The only reason we could special-case primitives is because we have a list of all possible primitives ahead of time. --- .../passes/collect_intra_doc_links.rs | 33 ++++++++++++++++--- .../rustdoc/intra-link-prim-precedence.rs | 12 +++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 src/test/rustdoc/intra-link-prim-precedence.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8da74f375d9ce..41a94dad0344d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -164,6 +164,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { fn resolve( &self, path_str: &str, + disambiguator: Option<&str>, ns: Namespace, current_item: &Option, parent_id: Option, @@ -203,11 +204,22 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } return Ok((res, Some(path_str.to_owned()))); } - other => { - debug!( - "failed to resolve {} in namespace {:?} (got {:?})", - path_str, ns, other - ); + Res::Def(DefKind::Mod, _) => { + // This resolved to a module, but if we were passed `type@`, + // we want primitive types to take precedence instead. + if disambiguator == Some("type") { + if let Some(prim) = is_primitive(path_str, ns) { + if extra_fragment.is_some() { + return Err(ErrorKind::AnchorFailure( + "primitive types cannot be followed by anchors", + )); + } + return Ok((prim, Some(path_str.to_owned()))); + } + } + return Ok((res, extra_fragment.clone())); + } + _ => { return Ok((res, extra_fragment.clone())); } }; @@ -566,11 +578,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let mut path_str; let (res, fragment) = { let mut kind = None; + let mut disambiguator = None; path_str = if let Some(prefix) = ["struct@", "enum@", "type@", "trait@", "union@"] .iter() .find(|p| link.starts_with(**p)) { kind = Some(TypeNS); + disambiguator = Some(&prefix[..prefix.len() - 1]); link.trim_start_matches(prefix) } else if let Some(prefix) = [ "const@", @@ -586,18 +600,23 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { .find(|p| link.starts_with(**p)) { kind = Some(ValueNS); + disambiguator = Some(&prefix[..prefix.len() - 1]); link.trim_start_matches(prefix) } else if link.ends_with("()") { kind = Some(ValueNS); + disambiguator = Some("fn"); link.trim_end_matches("()") } else if link.starts_with("macro@") { kind = Some(MacroNS); + disambiguator = Some("macro"); link.trim_start_matches("macro@") } else if link.starts_with("derive@") { kind = Some(MacroNS); + disambiguator = Some("derive"); link.trim_start_matches("derive@") } else if link.ends_with('!') { kind = Some(MacroNS); + disambiguator = Some("macro"); link.trim_end_matches('!') } else { &link[..] @@ -634,6 +653,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { Some(ns @ ValueNS) => { match self.resolve( path_str, + disambiguator, ns, ¤t_item, base_node, @@ -657,6 +677,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { Some(ns @ TypeNS) => { match self.resolve( path_str, + disambiguator, ns, ¤t_item, base_node, @@ -683,6 +704,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { .map(|res| (res, extra_fragment.clone())), type_ns: match self.resolve( path_str, + disambiguator, TypeNS, ¤t_item, base_node, @@ -697,6 +719,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }, value_ns: match self.resolve( path_str, + disambiguator, ValueNS, ¤t_item, base_node, diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs new file mode 100644 index 0000000000000..ca83d5e2281a7 --- /dev/null +++ b/src/test/rustdoc/intra-link-prim-precedence.rs @@ -0,0 +1,12 @@ +// ignore-tidy-linelength +#![deny(intra_doc_resolution_failure)] + +pub mod char {} + +/// See also [type@char] +// @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html' +pub struct MyString; + +/// See also [char] +// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html' +pub struct MyString2; From 7610ab36f8aa7d0a683de36dbd919e87fbe9bbb1 Mon Sep 17 00:00:00 2001 From: pierwill <19642016+pierwill@users.noreply.github.com> Date: Mon, 6 Jul 2020 14:30:37 -0700 Subject: [PATCH 16/16] Expand abbreviation in core::ffi description --- src/libcore/ffi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index ca4632006509f..ee3192eddbd06 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -1,7 +1,7 @@ #![stable(feature = "", since = "1.30.0")] #![allow(non_camel_case_types)] -//! Utilities related to FFI bindings. +//! Utilities related to foreign function interface (FFI) bindings. use crate::fmt; use crate::marker::PhantomData;