From 08f204e17f1f007d844743802e04d7f62689e966 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 4 Apr 2023 14:15:29 -0700 Subject: [PATCH 01/15] rustdoc: migrate `document_type_layout` to askama --- src/librustdoc/html/render/print_item.rs | 166 +++++++----------- .../html/templates/type_layout.html | 45 +++++ 2 files changed, 112 insertions(+), 99 deletions(-) create mode 100644 src/librustdoc/html/templates/type_layout.html diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6bce57340040b..e089b55b9c4d1 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,13 +5,15 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; +use rustc_index::vec::IndexVec; use rustc_middle::middle::stability; use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; use rustc_middle::ty::{self, Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{LayoutS, Primitive, TagEncoding, Variants}; +use rustc_target::abi::{LayoutS, Primitive, TagEncoding, VariantIdx, Variants}; +use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; @@ -1936,111 +1938,77 @@ fn document_type_layout<'a, 'cx: 'a>( cx: &'a Context<'cx>, ty_def_id: DefId, ) -> impl fmt::Display + 'a + Captures<'cx> { - fn write_size_of_layout(mut w: impl fmt::Write, layout: &LayoutS, tag_size: u64) { - if layout.abi.is_unsized() { - write!(w, "(unsized)").unwrap(); - } else { - let size = layout.size.bytes() - tag_size; - write!(w, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" }).unwrap(); - if layout.abi.is_uninhabited() { - write!( - w, - " (uninhabited)" - ).unwrap(); - } - } + #[derive(Template)] + #[template(path = "type_layout.html")] + struct TypeLayout<'a, 'cx> { + cx: &'a Context<'cx>, + ty_def_id: DefId, } - display_fn(move |mut f| { - if !cx.shared.show_type_layout { - return Ok(()); + impl<'a, 'cx: 'a> TypeLayout<'a, 'cx> { + fn variants<'b: 'a>(&'b self) -> Option<&'b IndexVec> { + if let Variants::Multiple { variants, .. } = + self.type_layout().unwrap().layout.variants() && !variants.is_empty() { + Some(&variants) + } else { + None + } } - - writeln!( - f, - "

\ - Layout§

" - )?; - writeln!(f, "
")?; - - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - match tcx.layout_of(param_env.and(ty)) { - Ok(ty_layout) => { - writeln!( - f, - "

Note: Most layout information is \ - completely unstable and may even differ between compilations. \ - The only exception is types with certain repr(...) attributes. \ - Please see the Rust Reference’s \ - “Type Layout” \ - chapter for details on type layout guarantees.

" - )?; - f.write_str("

Size: ")?; - write_size_of_layout(&mut f, &ty_layout.layout.0, 0); - writeln!(f, "

")?; - if let Variants::Multiple { variants, tag, tag_encoding, .. } = - &ty_layout.layout.variants() - { - if !variants.is_empty() { - f.write_str( - "

Size for each variant:

\ -
    ", + fn type_layout<'b: 'a>(&'b self) -> Result, LayoutError<'cx>> { + let tcx = self.cx.tcx(); + let param_env = tcx.param_env(self.ty_def_id); + let ty = tcx.type_of(self.ty_def_id).subst_identity(); + tcx.layout_of(param_env.and(ty)) + } + fn variant_name<'b: 'a>(&'b self, index: VariantIdx) -> Symbol { + let Adt(adt, _) = self.type_layout().unwrap().ty.kind() else { + span_bug!(self.cx.tcx().def_span(self.ty_def_id), "not an adt") + }; + adt.variant(index).name + } + fn tag_size<'b: 'a>(&'b self) -> u64 { + if let Variants::Multiple { variants, tag, tag_encoding, .. } = + self.type_layout().unwrap().layout.variants() && !variants.is_empty() { + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(self.cx.tcx().def_span(self.ty_def_id), "tag is neither niche nor int") + } + } else { + 0 + } + } + fn write_size<'b: 'a>( + &'b self, + layout: &'b LayoutS, + tag_size: u64, + ) -> impl fmt::Display + Captures<'cx> + Captures<'b> { + display_fn(move |f| { + if layout.abi.is_unsized() { + write!(f, "(unsized)")?; + } else { + let size = layout.size.bytes() - tag_size; + write!(f, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" })?; + if layout.abi.is_uninhabited() { + write!( + f, + " (uninhabited)" )?; - - let Adt(adt, _) = ty_layout.ty.kind() else { - span_bug!(tcx.def_span(ty_def_id), "not an adt") - }; - - let tag_size = if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int") - }; - - for (index, layout) in variants.iter_enumerated() { - let name = adt.variant(index).name; - write!(&mut f, "
  • {name}: ")?; - write_size_of_layout(&mut f, layout, tag_size); - writeln!(&mut f, "
  • ")?; - } - f.write_str("
")?; } } - } - // This kind of layout error can occur with valid code, e.g. if you try to - // get the layout of a generic type such as `Vec`. - Err(LayoutError::Unknown(_)) => { - writeln!( - f, - "

Note: Unable to compute type layout, \ - possibly due to this type having generic parameters. \ - Layout can only be computed for concrete, fully-instantiated types.

" - )?; - } - // This kind of error probably can't happen with valid code, but we don't - // want to panic and prevent the docs from building, so we just let the - // user know that we couldn't compute the layout. - Err(LayoutError::SizeOverflow(_)) => { - writeln!( - f, - "

Note: Encountered an error during type layout; \ - the type was too big.

" - )?; - } - Err(LayoutError::NormalizationFailure(_, _)) => { - writeln!( - f, - "

Note: Encountered an error during type layout; \ - the type failed to be normalized.

" - )?; - } + Ok(()) + }) + } + } + + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); } - writeln!(f, "
") + Ok(TypeLayout { cx, ty_def_id }.render_into(f).unwrap()) }) } diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html new file mode 100644 index 0000000000000..70149d4e1ab85 --- /dev/null +++ b/src/librustdoc/html/templates/type_layout.html @@ -0,0 +1,45 @@ +

{# #} + Layout§ {# #} +

{# #} +
{# #} + {% match self.type_layout() %} + {% when Ok(ty_layout) %} +
{# #} +

{# #} + Note: Most layout information is completely {#+ #} + unstable and may even differ between compilations. {#+ #} + The only exception is types with certain repr(...) {#+ #} + attributes. Please see the Rust Reference’s {#+ #} + “Type Layout” {#+ #} + chapter for details on type layout guarantees. {# #} +

{# #} +
{# #} +

Size: {{ self.write_size(ty_layout.layout.0.borrow(), 0) | safe }}

{# #} + {% if let Some(variants) = self.variants() %} +

Size for each variant:

{# #} +
    {# #} + {% for (index, layout) in variants.iter_enumerated() %} +
  • {# #} + {{ self.variant_name(index.clone()) }}: {#+ #} + {{ self.write_size(layout, self.tag_size()) | safe }} +
  • {# #} + {% endfor %} +
{# #} + {% endif %} + {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec`. #} + {% when Err(LayoutError::Unknown(_)) %} +

Note: Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types.

{# #} + {# This kind of error probably can't happen with valid code, but we don't + want to panic and prevent the docs from building, so we just let the + user know that we couldn't compute the layout. #} + {% when Err(LayoutError::SizeOverflow(_)) %} +

Note: Encountered an error during type layout; {#+ #} + the type was too big.

{# #} + {% when Err(LayoutError::NormalizationFailure(_, _)) %} +

Note: Encountered an error during type layout; {#+ #} + the type failed to be normalized.

{# #} + {% endmatch %} +
{# #} From 5f9746b94766e1dca4c4ee39da46a03a41d3fcd8 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 18 Apr 2023 10:21:04 -0700 Subject: [PATCH 02/15] rustdoc: use a separate template for type layout size --- src/librustdoc/html/render/print_item.rs | 24 +++++++++---------- .../html/templates/type_layout_size.html | 12 ++++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 src/librustdoc/html/templates/type_layout_size.html diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index e089b55b9c4d1..3045e4b118bfb 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1945,6 +1945,14 @@ fn document_type_layout<'a, 'cx: 'a>( ty_def_id: DefId, } + #[derive(Template)] + #[template(path = "type_layout_size.html")] + struct TypeLayoutSize { + is_unsized: bool, + is_uninhabited: bool, + size: u64, + } + impl<'a, 'cx: 'a> TypeLayout<'a, 'cx> { fn variants<'b: 'a>(&'b self) -> Option<&'b IndexVec> { if let Variants::Multiple { variants, .. } = @@ -1986,18 +1994,10 @@ fn document_type_layout<'a, 'cx: 'a>( tag_size: u64, ) -> impl fmt::Display + Captures<'cx> + Captures<'b> { display_fn(move |f| { - if layout.abi.is_unsized() { - write!(f, "(unsized)")?; - } else { - let size = layout.size.bytes() - tag_size; - write!(f, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" })?; - if layout.abi.is_uninhabited() { - write!( - f, - " (uninhabited)" - )?; - } - } + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes() - tag_size; + TypeLayoutSize { is_unsized, is_uninhabited, size }.render_into(f).unwrap(); Ok(()) }) } diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html new file mode 100644 index 0000000000000..9c2b39edc9f37 --- /dev/null +++ b/src/librustdoc/html/templates/type_layout_size.html @@ -0,0 +1,12 @@ +{% if is_unsized %} + (unsized) +{% else %} + {% if size == 1 %} + 1 byte + {% else %} + {{ size +}} bytes + {% endif %} + {% if is_uninhabited %} + {# +#} (uninhabited) + {% endif %} +{% endif %} From 3a16db1bb4c863b2afe5ecd745c1d7a7741a5e11 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 18 Apr 2023 10:49:18 -0700 Subject: [PATCH 03/15] rustdoc: create variants list outside of template --- src/librustdoc/html/render/print_item.rs | 109 +++++++++--------- .../html/templates/type_layout.html | 14 +-- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3045e4b118bfb..3ccc694fd2a75 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,15 +5,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; use rustc_middle::middle::stability; use rustc_middle::span_bug; -use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; +use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{LayoutS, Primitive, TagEncoding, VariantIdx, Variants}; -use std::borrow::Borrow; +use rustc_target::abi::{Primitive, TagEncoding, Variants}; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; @@ -1940,9 +1938,9 @@ fn document_type_layout<'a, 'cx: 'a>( ) -> impl fmt::Display + 'a + Captures<'cx> { #[derive(Template)] #[template(path = "type_layout.html")] - struct TypeLayout<'a, 'cx> { - cx: &'a Context<'cx>, - ty_def_id: DefId, + struct TypeLayout<'cx> { + variants: Vec<(Symbol, TypeLayoutSize)>, + type_layout_size: Result>, } #[derive(Template)] @@ -1953,62 +1951,61 @@ fn document_type_layout<'a, 'cx: 'a>( size: u64, } - impl<'a, 'cx: 'a> TypeLayout<'a, 'cx> { - fn variants<'b: 'a>(&'b self) -> Option<&'b IndexVec> { - if let Variants::Multiple { variants, .. } = - self.type_layout().unwrap().layout.variants() && !variants.is_empty() { - Some(&variants) - } else { - None - } - } - fn type_layout<'b: 'a>(&'b self) -> Result, LayoutError<'cx>> { - let tcx = self.cx.tcx(); - let param_env = tcx.param_env(self.ty_def_id); - let ty = tcx.type_of(self.ty_def_id).subst_identity(); - tcx.layout_of(param_env.and(ty)) + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); } - fn variant_name<'b: 'a>(&'b self, index: VariantIdx) -> Symbol { - let Adt(adt, _) = self.type_layout().unwrap().ty.kind() else { - span_bug!(self.cx.tcx().def_span(self.ty_def_id), "not an adt") - }; - adt.variant(index).name - } - fn tag_size<'b: 'a>(&'b self) -> u64 { - if let Variants::Multiple { variants, tag, tag_encoding, .. } = - self.type_layout().unwrap().layout.variants() && !variants.is_empty() { - if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(self.cx.tcx().def_span(self.ty_def_id), "tag is neither niche nor int") - } + + let variants = { + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + if let Ok(type_layout) = type_layout && + let Variants::Multiple { variants, tag, tag_encoding, .. } = + type_layout.layout.variants() && + !variants.is_empty() + { + let tag_size = + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") + }; + let variants = variants + .iter_enumerated() + .map(|(variant_idx, variant_layout)| { + let Adt(adt, _) = type_layout.ty.kind() else { + span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") + }; + let name = adt.variant(variant_idx).name; + let is_unsized = variant_layout.abi.is_unsized(); + let is_uninhabited = variant_layout.abi.is_uninhabited(); + let size = variant_layout.size.bytes() - tag_size; + let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; + (name, type_layout_size) + }).collect(); + variants } else { - 0 + Vec::new() } - } - fn write_size<'b: 'a>( - &'b self, - layout: &'b LayoutS, - tag_size: u64, - ) -> impl fmt::Display + Captures<'cx> + Captures<'b> { - display_fn(move |f| { + }; + + let type_layout_size = { + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + tcx.layout_of(param_env.and(ty)).map(|layout| { let is_unsized = layout.abi.is_unsized(); let is_uninhabited = layout.abi.is_uninhabited(); - let size = layout.size.bytes() - tag_size; - TypeLayoutSize { is_unsized, is_uninhabited, size }.render_into(f).unwrap(); - Ok(()) + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } }) - } - } - - display_fn(move |f| { - if !cx.shared.show_type_layout { - return Ok(()); - } + }; - Ok(TypeLayout { cx, ty_def_id }.render_into(f).unwrap()) + Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) }) } diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index 70149d4e1ab85..9e2c2049e31bb 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -2,8 +2,8 @@

{# #} Layout§ {# #}

{# #}
{# #} - {% match self.type_layout() %} - {% when Ok(ty_layout) %} + {% match type_layout_size %} + {% when Ok(type_layout_size) %}
{# #}

{# #} Note: Most layout information is completely {#+ #} @@ -14,14 +14,14 @@

{# #} chapter for details on type layout guarantees. {# #}

{# #}

{# #} -

Size: {{ self.write_size(ty_layout.layout.0.borrow(), 0) | safe }}

{# #} - {% if let Some(variants) = self.variants() %} +

Size: {{ type_layout_size|safe }}

{# #} + {% if !variants.is_empty() %}

Size for each variant:

{# #}
    {# #} - {% for (index, layout) in variants.iter_enumerated() %} + {% for (name, layout_size) in variants %}
  • {# #} - {{ self.variant_name(index.clone()) }}: {#+ #} - {{ self.write_size(layout, self.tag_size()) | safe }} + {{ name }}: {#+ #} + {{ layout_size|safe }}
  • {# #} {% endfor %}
{# #} From e26ae9530b21288ea6f9ca73d8c8d895c47807c3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 18 Apr 2023 10:52:36 -0700 Subject: [PATCH 04/15] rustdoc: format type layout template with newline after `

` --- .../html/templates/type_layout.html | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index 9e2c2049e31bb..58b220c7428f4 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -16,7 +16,9 @@

{# #}

{# #}

Size: {{ type_layout_size|safe }}

{# #} {% if !variants.is_empty() %} -

Size for each variant:

{# #} +

{# #} + Size for each variant: {# #} +

{# #}
    {# #} {% for (name, layout_size) in variants %}
  • {# #} @@ -29,17 +31,23 @@

    {# #} {# This kind of layout error can occur with valid code, e.g. if you try to get the layout of a generic type such as `Vec`. #} {% when Err(LayoutError::Unknown(_)) %} -

    Note: Unable to compute type layout, {#+ #} - possibly due to this type having generic parameters. {#+ #} - Layout can only be computed for concrete, fully-instantiated types.

    {# #} +

    {# #} + Note: Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} +

    {# #} {# This kind of error probably can't happen with valid code, but we don't want to panic and prevent the docs from building, so we just let the user know that we couldn't compute the layout. #} {% when Err(LayoutError::SizeOverflow(_)) %} -

    Note: Encountered an error during type layout; {#+ #} - the type was too big.

    {# #} +

    {# #} + Note: Encountered an error during type layout; {#+ #} + the type was too big. {# #} +

    {# #} {% when Err(LayoutError::NormalizationFailure(_, _)) %} -

    Note: Encountered an error during type layout; {#+ #} - the type failed to be normalized.

    {# #} +

    {# #} + Note: Encountered an error during type layout; {#+ #} + the type failed to be normalized. {# #} +

    {# #} {% endmatch %} {# #} From 4375af53af48febdd3534d8d300b7769a4e0fb1c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 20 Apr 2023 18:46:29 +0000 Subject: [PATCH 05/15] Derive `HashStable` on `GenericArgKind` instead of implementing it by hand --- compiler/rustc_middle/src/ty/impls_ty.rs | 28 ------------------------ compiler/rustc_middle/src/ty/subst.rs | 2 +- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 4c7822acdf785..02baa395c3c2f 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -73,34 +73,6 @@ impl<'a, 'tcx> HashStable> for ty::subst::GenericArg<'t } } -impl<'a, 'tcx> HashStable> for ty::subst::GenericArgKind<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - match self { - // WARNING: We dedup cache the `HashStable` results for `List` - // while ignoring types and freely transmute - // between `List>` and `List>`. - // See `fn mk_type_list` for more details. - // - // We therefore hash types without adding a hash for their discriminant. - // - // In order to make it very unlikely for the sequence of bytes being hashed for - // a `GenericArgKind::Type` to be the same as the sequence of bytes being - // hashed for one of the other variants, we hash some very high number instead - // of their actual discriminant since `TyKind` should never start with anything - // that high. - ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher), - ty::subst::GenericArgKind::Const(ct) => { - 0xF3u8.hash_stable(hcx, hasher); - ct.hash_stable(hcx, hasher); - } - ty::subst::GenericArgKind::Lifetime(lt) => { - 0xF5u8.hash_stable(hcx, hasher); - lt.hash_stable(hcx, hasher); - } - } - } -} - // AllocIds get resolved to whatever they point to (to be stable) impl<'a> HashStable> for mir::interpret::AllocId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 3e1b0706f6688..2b85eb971ce83 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -48,7 +48,7 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), From b0692a626b9247fe01f2009fb8a112f05942b5a4 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 21 Apr 2023 13:27:13 +0200 Subject: [PATCH 06/15] compiler/rustc_target: Raise m68k-linux-gnu baseline to 68020 Atomic operations require 68020 or later on m68k-linux-gnu. --- compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs index ebd74012dcd2c..9bcd56bed0025 100644 --- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs @@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); + base.cpu = "M68020".into(); base.max_atomic_width = Some(32); Target { From 99e1cdb46f1b26ba8b458dded654f7f6a59973bc Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 09:00:33 -0700 Subject: [PATCH 07/15] rustdoc: get rid of redundant, nested `let` lines --- src/librustdoc/html/render/print_item.rs | 30 ++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3ccc694fd2a75..fe227244588b4 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1956,11 +1956,12 @@ fn document_type_layout<'a, 'cx: 'a>( return Ok(()); } - let variants = { - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - let type_layout = tcx.layout_of(param_env.and(ty)); + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + + let variants = if let Ok(type_layout) = type_layout && let Variants::Multiple { variants, tag, tag_encoding, .. } = type_layout.layout.variants() && @@ -1991,19 +1992,14 @@ fn document_type_layout<'a, 'cx: 'a>( } else { Vec::new() } - }; + ; - let type_layout_size = { - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - tcx.layout_of(param_env.and(ty)).map(|layout| { - let is_unsized = layout.abi.is_unsized(); - let is_uninhabited = layout.abi.is_uninhabited(); - let size = layout.size.bytes(); - TypeLayoutSize { is_unsized, is_uninhabited, size } - }) - }; + let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } + }); Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) }) From 2b728c1f85dec11fd0e64ad89c7149e119134971 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 10:06:31 -0700 Subject: [PATCH 08/15] rustdoc: factor `document_type_layout` into its own module --- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/render/print_item.rs | 79 +------------------- src/librustdoc/html/render/type_layout.rs | 87 +++++++++++++++++++++++ 3 files changed, 90 insertions(+), 77 deletions(-) create mode 100644 src/librustdoc/html/render/type_layout.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1e3cd2668506f..a699d0b38a70c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -32,6 +32,7 @@ mod context; mod print_item; mod sidebar; mod span_map; +mod type_layout; mod write_shared; pub(crate) use self::context::*; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index fe227244588b4..b71109f15609e 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -6,16 +6,14 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::stability; -use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self, Adt, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{Primitive, TagEncoding, Variants}; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; +use super::type_layout::document_type_layout; use super::{ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, @@ -1932,79 +1930,6 @@ fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a }) } -fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { - #[derive(Template)] - #[template(path = "type_layout.html")] - struct TypeLayout<'cx> { - variants: Vec<(Symbol, TypeLayoutSize)>, - type_layout_size: Result>, - } - - #[derive(Template)] - #[template(path = "type_layout_size.html")] - struct TypeLayoutSize { - is_unsized: bool, - is_uninhabited: bool, - size: u64, - } - - display_fn(move |f| { - if !cx.shared.show_type_layout { - return Ok(()); - } - - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - let type_layout = tcx.layout_of(param_env.and(ty)); - - let variants = - if let Ok(type_layout) = type_layout && - let Variants::Multiple { variants, tag, tag_encoding, .. } = - type_layout.layout.variants() && - !variants.is_empty() - { - let tag_size = - if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") - }; - let variants = variants - .iter_enumerated() - .map(|(variant_idx, variant_layout)| { - let Adt(adt, _) = type_layout.ty.kind() else { - span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") - }; - let name = adt.variant(variant_idx).name; - let is_unsized = variant_layout.abi.is_unsized(); - let is_uninhabited = variant_layout.abi.is_uninhabited(); - let size = variant_layout.size.bytes() - tag_size; - let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; - (name, type_layout_size) - }).collect(); - variants - } else { - Vec::new() - } - ; - - let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { - let is_unsized = layout.abi.is_unsized(); - let is_uninhabited = layout.abi.is_uninhabited(); - let size = layout.size.bytes(); - TypeLayoutSize { is_unsized, is_uninhabited, size } - }); - - Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) - }) -} - fn pluralize(count: usize) -> &'static str { if count > 1 { "s" } else { "" } } diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs new file mode 100644 index 0000000000000..0befc9625db78 --- /dev/null +++ b/src/librustdoc/html/render/type_layout.rs @@ -0,0 +1,87 @@ +use askama::Template; + +use rustc_data_structures::captures::Captures; +use rustc_hir::def_id::DefId; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::Adt; +use rustc_span::symbol::Symbol; +use rustc_target::abi::{Primitive, TagEncoding, Variants}; + +use std::fmt; + +use crate::html::format::display_fn; +use crate::html::render::Context; + +#[derive(Template)] +#[template(path = "type_layout.html")] +struct TypeLayout<'cx> { + variants: Vec<(Symbol, TypeLayoutSize)>, + type_layout_size: Result>, +} + +#[derive(Template)] +#[template(path = "type_layout_size.html")] +struct TypeLayoutSize { + is_unsized: bool, + is_uninhabited: bool, + size: u64, +} + +pub(crate) fn document_type_layout<'a, 'cx: 'a>( + cx: &'a Context<'cx>, + ty_def_id: DefId, +) -> impl fmt::Display + 'a + Captures<'cx> { + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); + } + + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + + let variants = + if let Ok(type_layout) = type_layout && + let Variants::Multiple { variants, tag, tag_encoding, .. } = + type_layout.layout.variants() && + !variants.is_empty() + { + let tag_size = + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") + }; + let variants = variants + .iter_enumerated() + .map(|(variant_idx, variant_layout)| { + let Adt(adt, _) = type_layout.ty.kind() else { + span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") + }; + let name = adt.variant(variant_idx).name; + let is_unsized = variant_layout.abi.is_unsized(); + let is_uninhabited = variant_layout.abi.is_uninhabited(); + let size = variant_layout.size.bytes() - tag_size; + let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; + (name, type_layout_size) + }).collect(); + variants + } else { + Vec::new() + } + ; + + let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } + }); + + Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) + }) +} From e6664c06813b25c2edd923a8a69d57ae98b6083f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 11:05:24 -0700 Subject: [PATCH 09/15] rustdoc: remove unnecessary binding --- src/librustdoc/html/render/type_layout.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 0befc9625db78..22aec623335e8 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -56,7 +56,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( } else { span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") }; - let variants = variants + variants .iter_enumerated() .map(|(variant_idx, variant_layout)| { let Adt(adt, _) = type_layout.ty.kind() else { @@ -68,12 +68,11 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( let size = variant_layout.size.bytes() - tag_size; let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; (name, type_layout_size) - }).collect(); - variants + }) + .collect() } else { Vec::new() - } - ; + }; let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { let is_unsized = layout.abi.is_unsized(); From 6f29a3c98036d14e634a88326efc93fd1d8a70ff Mon Sep 17 00:00:00 2001 From: miguelraz Date: Fri, 21 Apr 2023 15:45:25 -0600 Subject: [PATCH 10/15] nit: consistent naming for SimplifyConstCondition --- compiler/rustc_mir_transform/src/lib.rs | 4 ++-- compiler/rustc_mir_transform/src/simplify_branches.rs | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 7a2420a6d940d..7d04aead8bc59 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -507,12 +507,12 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &const_debuginfo::ConstDebugInfo, - &o1(simplify_branches::SimplifyConstConditionPassName::AfterConstProp), + &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, &dead_store_elimination::DeadStoreElimination, &dest_prop::DestinationPropagation, - &o1(simplify_branches::SimplifyConstConditionPassName::Final), + &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), &o1(simplify::SimplifyCfg::Final), &nrvo::RenameReturnPlace, diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index ddaf86a9e730f..c65a7ec6783fa 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -2,18 +2,16 @@ use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -pub enum SimplifyConstConditionPassName { +pub enum SimplifyConstCondition { AfterConstProp, Final, } /// A pass that replaces a branch with a goto when its condition is known. -impl<'tcx> MirPass<'tcx> for SimplifyConstConditionPassName { +impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { fn name(&self) -> &'static str { match self { - SimplifyConstConditionPassName::AfterConstProp => { - "SimplifyConstCondition-after-const-prop" - } - SimplifyConstConditionPassName::Final => "SimplifyConstCondition-final", + SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop", + SimplifyConstCondition::Final => "SimplifyConstCondition-final", } } From 994dd696cbebe986923ab44aabda9e0d788ce3f5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 14:51:52 -0700 Subject: [PATCH 11/15] rustdoc: use Set for ignored crates, instead of string matching --- src/librustdoc/html/static/js/main.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 93d657fd60509..b1c6eaee70d0e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -533,9 +533,11 @@ function preLoadCss(cssUrl) { // ignored are included in the attribute `data-ignore-extern-crates`. const script = document .querySelector("script[data-ignore-extern-crates]"); - const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; + const ignoreExternCrates = new Set( + (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",") + ); for (const lib of libs) { - if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { + if (lib === window.currentCrate || ignoreExternCrates.has(lib)) { continue; } const structs = imp[lib]; From 9d69ee0574b2d315d692af1ad94c211a448101eb Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 14:57:09 -0700 Subject: [PATCH 12/15] rustdoc: lift constant string manipulation out of loop --- src/librustdoc/html/static/js/source-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 9aa75517330cd..d999f3b36fd82 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -52,12 +52,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const files = document.createElement("div"); files.className = "files"; if (elem[FILES_OFFSET]) { + const w = window.location.href.split("#")[0]; for (const file_text of elem[FILES_OFFSET]) { const file = document.createElement("a"); file.innerText = file_text; file.href = rootPath + "src/" + fullPath + file_text + ".html"; file.addEventListener("click", closeSidebarIfMobile); - const w = window.location.href.split("#")[0]; if (!hasFoundFile && w === file.href) { file.className = "selected"; dirEntry.open = true; From 0cd387415558729c72962bf8f47d229f0b93ce50 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 15:07:52 -0700 Subject: [PATCH 13/15] rustdoc: clean up redundant search hiding results code * There's no need to call `history.replaceState` right before calling `searchState.hideResults`, which already does it. * There's no need to implement hiding search results when that is already implemented. --- src/librustdoc/html/static/js/main.js | 5 +---- src/librustdoc/html/static/js/search.js | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b1c6eaee70d0e..bccf675c14b5e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -375,10 +375,7 @@ function preLoadCss(cssUrl) { function handleEscape(ev) { searchState.clearInputTimeout(); - switchDisplayedElement(null); - if (browserSupportsHistoryApi()) { - history.replaceState(null, "", getNakedUrl() + window.location.hash); - } + searchState.hideResults(); ev.preventDefault(); searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 929dae81c8de4..3dc4f2149b8b9 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2412,10 +2412,6 @@ function initSearch(rawSearchIndex) { const searchAfter500ms = () => { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } searchState.hideResults(); } else { searchState.timeout = setTimeout(search, 500); From 56613f8c382351898f9267bac8e8324f118eb79d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 20 Apr 2023 20:15:04 -0700 Subject: [PATCH 14/15] More `IS_ZST` in `library` I noticed that `post_inc_start` and `pre_dec_end` were doing this check in different ways https://github.com/rust-lang/rust/blob/d19b64fb54391b64ce99981577c67c93ac2a9ffa/library/core/src/slice/iter/macros.rs#L76-L93 so started making this PR, then added a few more I found since I was already making changes anyway. --- library/alloc/src/boxed/thin.rs | 10 +++------- library/alloc/src/vec/drain.rs | 4 +--- library/alloc/src/vec/drain_filter.rs | 6 ++---- library/core/src/slice/iter/macros.rs | 2 +- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index ad48315fd70cc..f83c8f83cc989 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; use core::ptr::{self, NonNull}; @@ -202,9 +202,7 @@ impl WithHeader { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::() == 0 && mem::size_of::() == 0 - ); + debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -249,9 +247,7 @@ impl WithHeader { alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); } else { debug_assert!( - value_offset == 0 - && mem::size_of::() == 0 - && self.value_layout.size() == 0 + value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0 ); } } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 2b1a787cc5499..45b03fb680b68 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { let unyielded_ptr = this.iter.as_slice().as_ptr(); // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::() != 0; - - if needs_move { + if !T::IS_ZST { let start_ptr = source_vec.as_mut_ptr().add(start); // memmove back unyielded elements diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index 8c03f1692d940..650f921389028 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -1,5 +1,5 @@ use crate::alloc::{Allocator, Global}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ptr; use core::slice; @@ -96,9 +96,7 @@ where unsafe { // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::() != 0; - - if needs_move && this.idx < this.old_len && this.del > 0 { + if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { let ptr = this.vec.as_mut_ptr(); let src = ptr.add(this.idx); let dst = src.sub(this.del); diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b73e35f1e9138..b1ca872b84549 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -73,7 +73,7 @@ macro_rules! iterator { // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T { - if mem::size_of::() == 0 { + if T::IS_ZST { zst_shrink!(self, offset); self.ptr.as_ptr() } else { From 1d7a2472bf88da7364235334902321be32408388 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Apr 2023 21:02:30 +0000 Subject: [PATCH 15/15] Print ty placeholders pretty --- compiler/rustc_middle/src/ty/print/pretty.rs | 16 +++++++++++++++- compiler/rustc_type_ir/src/sty.rs | 10 ++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5315aa155a831..888b3a50b77e9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -738,7 +738,9 @@ pub trait PrettyPrinter<'tcx>: } } ty::Placeholder(placeholder) => match placeholder.bound.kind { - ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)), + ty::BoundTyKind::Anon => { + self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { @@ -1172,6 +1174,18 @@ pub trait PrettyPrinter<'tcx>: } } + fn pretty_print_placeholder_var( + &mut self, + ui: ty::UniverseIndex, + var: ty::BoundVar, + ) -> Result<(), Self::Error> { + if ui == ty::UniverseIndex::ROOT { + write!(self, "!{}", var.index()) + } else { + write!(self, "!{}_{}", ui.index(), var.index()) + } + } + fn ty_infer_name(&self, _: ty::TyVid) -> Option { None } diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 62e699eefd706..4c1f2dd0e5334 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -203,6 +203,10 @@ pub enum TyKind { /// `for<'a, T> &'a (): Trait` and then convert the introduced bound variables /// back to inference variables in a new inference context when inside of the query. /// + /// It is conventional to render anonymous bound types like `^N` or `^D_N`, + /// where `N` is the bound variable's anonymous index into the binder, and + /// `D` is the debruijn index, or totally omitted if the debruijn index is zero. + /// /// See the `rustc-dev-guide` for more details about /// [higher-ranked trait bounds][1] and [canonical queries][2]. /// @@ -212,6 +216,12 @@ pub enum TyKind { /// A placeholder type, used during higher ranked subtyping to instantiate /// bound variables. + /// + /// It is conventional to render anonymous placeholer types like `!N` or `!U_N`, + /// where `N` is the placeholder variable's anonymous index (which corresponds + /// to the bound variable's index from the binder from which it was instantiated), + /// and `U` is the universe index in which it is instantiated, or totally omitted + /// if the universe index is zero. Placeholder(I::PlaceholderType), /// A type variable used during type checking.