about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-11-25 19:09:30 +0000
committerbors <bors@rust-lang.org>2022-11-25 19:09:30 +0000
commit8681d4cffcd23bbe619984ab62772a91827a40dc (patch)
tree32cc196f2843a02ea0ae3d08e50ccb1c96a6bedc
parent051cab2b842113b18da28259f4b85d0a7556f7f1 (diff)
parent12e1b84e95c05885d9f4714fe6dc2fceab0d2fe2 (diff)
downloadrust-8681d4cffcd23bbe619984ab62772a91827a40dc.tar.gz
rust-8681d4cffcd23bbe619984ab62772a91827a40dc.zip
Auto merge of #104902 - matthiaskrgr:rollup-oo27a4u, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #104716 (move 2 candidates into builtin candidate)
 - #104760 (Clarify `SyntaxExtensionKind::LegacyDerive`.)
 - #104797 (rustc_codegen_ssa: write `.dwp` in a streaming fashion)
 - #104835 (Use infcx.partially_normalize_associated_types_in)
 - #104853 (Fix typo in miri sysroot)
 - #104879 (jsondoclint: Recognise Typedef as valid kind for Type::ResolvedPath)
 - #104887 (rustbuild: Don't build doc::SharedAssets when building JSON docs.)
 - #104896 (rustdoc: fix broken tooltip CSS)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs9
-rw-r--r--compiler/rustc_expand/src/base.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs26
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs23
-rw-r--r--compiler/rustc_middle/src/traits/select.rs12
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs332
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs14
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--src/bootstrap/doc.rs4
-rw-r--r--src/bootstrap/test.rs2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css1
-rw-r--r--src/librustdoc/html/static/css/themes/light.css2
-rw-r--r--src/test/rustdoc-gui/codeblock-tooltip.goml2
-rw-r--r--src/test/rustdoc-json/fns/return_type_alias.rs10
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs4
-rw-r--r--src/tools/jsondoclint/src/validator.rs13
22 files changed, 251 insertions, 300 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 2091730af22..762430c6187 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -676,8 +676,7 @@ fn link_dwarf_object<'a>(
             thorin::MissingReferencedObjectBehaviour::Skip,
         )?;
 
-        let output = package.finish()?.write()?;
-        let mut output_stream = BufWriter::new(
+        let output_stream = BufWriter::new(
             OpenOptions::new()
                 .read(true)
                 .write(true)
@@ -685,8 +684,10 @@ fn link_dwarf_object<'a>(
                 .truncate(true)
                 .open(dwp_out_filename)?,
         );
-        output_stream.write_all(&output)?;
-        output_stream.flush()?;
+        let mut output_stream = object::write::StreamingBuffer::new(output_stream);
+        package.finish()?.emit(&mut output_stream)?;
+        output_stream.result()?;
+        output_stream.into_inner().flush()?;
 
         Ok(())
     }) {
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index bdcd5334949..8955abebf1e 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -676,8 +676,13 @@ pub enum SyntaxExtensionKind {
 
     /// A token-based derive macro.
     Derive(
-        /// An expander with signature TokenStream -> TokenStream (not yet).
+        /// An expander with signature TokenStream -> TokenStream.
         /// The produced TokenSteam is appended to the input TokenSteam.
+        ///
+        /// FIXME: The text above describes how this should work. Currently it
+        /// is handled identically to `LegacyDerive`. It should be migrated to
+        /// a token-based representation like `Bang` and `Attr`, instead of
+        /// using `MultiItemModifier`.
         Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
     ),
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 002467fb73e..6d858eacb45 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -31,6 +31,7 @@ use rustc_span::lev_distance::{
 use rustc_span::symbol::sym;
 use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::autoderef::{self, Autoderef};
+use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
 use rustc_trait_selection::traits::query::method_autoderef::{
@@ -716,9 +717,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
             // see issue #89650
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
-            let selcx = &mut traits::SelectionContext::new(self.fcx);
-            let traits::Normalized { value: xform_self_ty, obligations } =
-                traits::normalize(selcx, self.param_env, cause, xform_self_ty);
+            let InferOk { value: xform_self_ty, obligations } = self
+                .fcx
+                .partially_normalize_associated_types_in(cause, self.param_env, xform_self_ty);
+
             debug!(
                 "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
                 xform_self_ty, xform_ret_ty
@@ -1490,7 +1492,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             let mut xform_ret_ty = probe.xform_ret_ty;
             debug!(?xform_ret_ty);
 
-            let selcx = &mut traits::SelectionContext::new(self);
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
 
             let mut parent_pred = None;
@@ -1504,10 +1505,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
                     // see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
                     // for why this is necessary
-                    let traits::Normalized {
+                    let InferOk {
                         value: normalized_xform_ret_ty,
                         obligations: normalization_obligations,
-                    } = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty);
+                    } = self.fcx.partially_normalize_associated_types_in(
+                        cause.clone(),
+                        self.param_env,
+                        probe.xform_ret_ty,
+                    );
                     xform_ret_ty = normalized_xform_ret_ty;
                     debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
 
@@ -1515,8 +1520,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     let impl_def_id = probe.item.container_id(self.tcx);
                     let impl_bounds = self.tcx.predicates_of(impl_def_id);
                     let impl_bounds = impl_bounds.instantiate(self.tcx, substs);
-                    let traits::Normalized { value: impl_bounds, obligations: norm_obligations } =
-                        traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds);
+
+                    let InferOk { value: impl_bounds, obligations: norm_obligations } =
+                        self.fcx.partially_normalize_associated_types_in(
+                            cause.clone(),
+                            self.param_env,
+                            impl_bounds,
+                        );
 
                     // Convert the bounds into obligations.
                     let impl_obligations = traits::predicates_for_generics(
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 536d2872bf0..26f3052b642 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -651,12 +651,6 @@ pub enum ImplSource<'tcx, N> {
     /// Same as above, but for a function pointer type with the given signature.
     FnPointer(ImplSourceFnPointerData<'tcx, N>),
 
-    /// ImplSource for a builtin `DeterminantKind` trait implementation.
-    DiscriminantKind(ImplSourceDiscriminantKindData),
-
-    /// ImplSource for a builtin `Pointee` trait implementation.
-    Pointee(ImplSourcePointeeData),
-
     /// ImplSource automatically generated for a generator.
     Generator(ImplSourceGeneratorData<'tcx, N>),
 
@@ -682,8 +676,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::Future(c) => c.nested,
             ImplSource::Object(d) => d.nested,
             ImplSource::FnPointer(d) => d.nested,
-            ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            | ImplSource::Pointee(ImplSourcePointeeData) => vec![],
             ImplSource::TraitAlias(d) => d.nested,
             ImplSource::TraitUpcasting(d) => d.nested,
             ImplSource::ConstDestruct(i) => i.nested,
@@ -701,8 +693,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::Future(c) => &c.nested,
             ImplSource::Object(d) => &d.nested,
             ImplSource::FnPointer(d) => &d.nested,
-            ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            | ImplSource::Pointee(ImplSourcePointeeData) => &[],
             ImplSource::TraitAlias(d) => &d.nested,
             ImplSource::TraitUpcasting(d) => &d.nested,
             ImplSource::ConstDestruct(i) => &i.nested,
@@ -751,12 +741,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 fn_ty: p.fn_ty,
                 nested: p.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => {
-                ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            }
-            ImplSource::Pointee(ImplSourcePointeeData) => {
-                ImplSource::Pointee(ImplSourcePointeeData)
-            }
             ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
                 alias_def_id: d.alias_def_id,
                 substs: d.substs,
@@ -876,13 +860,6 @@ pub struct ImplSourceFnPointerData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-// FIXME(@lcnr): This should be  refactored and merged with other builtin vtables.
-#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
-pub struct ImplSourceDiscriminantKindData;
-
-#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
-pub struct ImplSourcePointeeData;
-
 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct ImplSourceConstDestructData<N> {
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 99bfa477f74..ec69864c951 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -105,6 +105,12 @@ pub type EvaluationCache<'tcx> = Cache<
 /// parameter environment.
 #[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)]
 pub enum SelectionCandidate<'tcx> {
+    /// A builtin implementation for some specific traits, used in cases
+    /// where we cannot rely an ordinary library implementations.
+    ///
+    /// The most notable examples are `sized`, `Copy` and `Clone`. This is also
+    /// used for the `DiscriminantKind` and `Pointee` trait, both of which have
+    /// an associated type.
     BuiltinCandidate {
         /// `false` if there are no *further* obligations.
         has_nested: bool,
@@ -141,12 +147,6 @@ pub enum SelectionCandidate<'tcx> {
         is_const: bool,
     },
 
-    /// Builtin implementation of `DiscriminantKind`.
-    DiscriminantKindCandidate,
-
-    /// Builtin implementation of `Pointee`.
-    PointeeCandidate,
-
     TraitAliasCandidate,
 
     /// Matching `dyn Trait` with a supertrait of `Trait`. The index is the
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 735cece8399..6acb7745d65 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -19,10 +19,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
 
             super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
 
-            super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::Pointee(ref d) => write!(f, "{:?}", d),
-
             super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
 
             super::ImplSource::Param(ref n, ct) => {
@@ -137,11 +133,3 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
         write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
     }
 }
-
-///////////////////////////////////////////////////////////////////////////
-// Lift implementations
-
-TrivialTypeTraversalAndLiftImpls! {
-    super::ImplSourceDiscriminantKindData,
-    super::ImplSourcePointeeData,
-}
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index e38b00a388d..4ac53f6302f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -9,6 +9,7 @@ use super::{
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::infer::InferCtxtExt as _;
 use crate::infer::{self, InferCtxt, TyCtxtInferExt};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::normalize::AtExt as _;
@@ -28,7 +29,7 @@ use rustc_hir::GenericParam;
 use rustc_hir::Item;
 use rustc_hir::Node;
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
-use rustc_infer::infer::TypeTrace;
+use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::ExpectedFound;
@@ -2530,18 +2531,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
 
         self.probe(|_| {
-            let mut selcx = SelectionContext::new(self);
-
             let cleaned_pred =
                 pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
 
-            let cleaned_pred = super::project::normalize(
-                &mut selcx,
-                param_env,
-                ObligationCause::dummy(),
-                cleaned_pred,
-            )
-            .value;
+            let InferOk { value: cleaned_pred, .. } =
+                self.infcx.partially_normalize_associated_types_in(
+                    ObligationCause::dummy(),
+                    param_env,
+                    cleaned_pred,
+                );
 
             let obligation =
                 Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 0113df5bdc6..5c13b6400ae 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1,11 +1,7 @@
-use super::{
-    DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
-    SelectionContext,
-};
+use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation};
 
 use crate::autoderef::Autoderef;
 use crate::infer::InferCtxt;
-use crate::traits::normalize_to;
 
 use hir::def::CtorOf;
 use hir::HirId;
@@ -23,7 +19,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::infer::LateBoundRegionConversionTime;
+use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
 use rustc_middle::hir::map;
 use rustc_middle::ty::{
     self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
@@ -2979,13 +2975,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         self.tcx.mk_substs_trait(trait_pred.self_ty(), []),
                     )
                 });
-                let projection_ty = normalize_to(
-                    &mut SelectionContext::new(self),
-                    obligation.param_env,
-                    obligation.cause.clone(),
-                    projection_ty,
-                    &mut vec![],
-                );
+                let InferOk { value: projection_ty, .. } = self
+                    .partially_normalize_associated_types_in(
+                        obligation.cause.clone(),
+                        obligation.param_env,
+                        projection_ty,
+                    );
 
                 debug!(
                     normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index c3605a4aab6..ae6fa841856 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -11,8 +11,7 @@ use super::Selection;
 use super::SelectionContext;
 use super::SelectionError;
 use super::{
-    ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
-    ImplSourceFutureData, ImplSourceGeneratorData, ImplSourcePointeeData,
+    ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
     ImplSourceUserDefinedData,
 };
 use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
@@ -29,6 +28,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
+use rustc_infer::traits::ImplSourceBuiltinData;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
@@ -1599,128 +1599,126 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                     }
                 }
             }
-            super::ImplSource::DiscriminantKind(..) => {
-                // While `DiscriminantKind` is automatically implemented for every type,
-                // the concrete discriminant may not be known yet.
-                //
-                // Any type with multiple potential discriminant types is therefore not eligible.
+            super::ImplSource::Builtin(..) => {
+                // While a builtin impl may be known to exist, the associated type may not yet
+                // be known. Any type with multiple potential associated types is therefore
+                // not eligible.
                 let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
 
-                match self_ty.kind() {
-                    ty::Bool
-                    | ty::Char
-                    | ty::Int(_)
-                    | ty::Uint(_)
-                    | ty::Float(_)
-                    | ty::Adt(..)
-                    | ty::Foreign(_)
-                    | ty::Str
-                    | ty::Array(..)
-                    | ty::Slice(_)
-                    | ty::RawPtr(..)
-                    | ty::Ref(..)
-                    | ty::FnDef(..)
-                    | ty::FnPtr(..)
-                    | ty::Dynamic(..)
-                    | ty::Closure(..)
-                    | ty::Generator(..)
-                    | ty::GeneratorWitness(..)
-                    | ty::Never
-                    | ty::Tuple(..)
-                    // Integers and floats always have `u8` as their discriminant.
-                    | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
-
-                    ty::Projection(..)
-                    | ty::Opaque(..)
-                    | ty::Param(..)
-                    | ty::Bound(..)
-                    | ty::Placeholder(..)
-                    | ty::Infer(..)
-                    | ty::Error(_) => false,
-                }
-            }
-            super::ImplSource::Pointee(..) => {
-                // While `Pointee` is automatically implemented for every type,
-                // the concrete metadata type may not be known yet.
-                //
-                // Any type with multiple potential metadata types is therefore not eligible.
-                let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
-
-                let tail = selcx.tcx().struct_tail_with_normalize(
-                    self_ty,
-                    |ty| {
-                        // We throw away any obligations we get from this, since we normalize
-                        // and confirm these obligations once again during confirmation
-                        normalize_with_depth(
-                            selcx,
-                            obligation.param_env,
-                            obligation.cause.clone(),
-                            obligation.recursion_depth + 1,
-                            ty,
-                        )
-                        .value
-                    },
-                    || {},
-                );
-
-                match tail.kind() {
-                    ty::Bool
-                    | ty::Char
-                    | ty::Int(_)
-                    | ty::Uint(_)
-                    | ty::Float(_)
-                    | ty::Str
-                    | ty::Array(..)
-                    | ty::Slice(_)
-                    | ty::RawPtr(..)
-                    | ty::Ref(..)
-                    | ty::FnDef(..)
-                    | ty::FnPtr(..)
-                    | ty::Dynamic(..)
-                    | ty::Closure(..)
-                    | ty::Generator(..)
-                    | ty::GeneratorWitness(..)
-                    | ty::Never
-                    // Extern types have unit metadata, according to RFC 2850
-                    | ty::Foreign(_)
-                    // If returned by `struct_tail_without_normalization` this is a unit struct
-                    // without any fields, or not a struct, and therefore is Sized.
-                    | ty::Adt(..)
-                    // If returned by `struct_tail_without_normalization` this is the empty tuple.
-                    | ty::Tuple(..)
-                    // Integers and floats are always Sized, and so have unit type metadata.
-                    | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
-
-                    // type parameters, opaques, and unnormalized projections have pointer
-                    // metadata if they're known (e.g. by the param_env) to be sized
-                    ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
-                        if selcx.infcx().predicate_must_hold_modulo_regions(
-                            &obligation.with(
-                                selcx.tcx(),
-                                ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref(
-                                    LangItem::Sized,
-                                    [self_ty],
-                                ))
-                                .without_const(),
-                            ),
-                        ) =>
-                    {
-                        true
+                let lang_items = selcx.tcx().lang_items();
+                if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
+                    match self_ty.kind() {
+                        ty::Bool
+                        | ty::Char
+                        | ty::Int(_)
+                        | ty::Uint(_)
+                        | ty::Float(_)
+                        | ty::Adt(..)
+                        | ty::Foreign(_)
+                        | ty::Str
+                        | ty::Array(..)
+                        | ty::Slice(_)
+                        | ty::RawPtr(..)
+                        | ty::Ref(..)
+                        | ty::FnDef(..)
+                        | ty::FnPtr(..)
+                        | ty::Dynamic(..)
+                        | ty::Closure(..)
+                        | ty::Generator(..)
+                        | ty::GeneratorWitness(..)
+                        | ty::Never
+                        | ty::Tuple(..)
+                        // Integers and floats always have `u8` as their discriminant.
+                        | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
+
+                         // type parameters, opaques, and unnormalized projections have pointer
+                        // metadata if they're known (e.g. by the param_env) to be sized
+                        ty::Param(_)
+                        | ty::Projection(..)
+                        | ty::Opaque(..)
+                        | ty::Bound(..)
+                        | ty::Placeholder(..)
+                        | ty::Infer(..)
+                        | ty::Error(_) => false,
                     }
+                } else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) {
+                    let tail = selcx.tcx().struct_tail_with_normalize(
+                        self_ty,
+                        |ty| {
+                            // We throw away any obligations we get from this, since we normalize
+                            // and confirm these obligations once again during confirmation
+                            normalize_with_depth(
+                                selcx,
+                                obligation.param_env,
+                                obligation.cause.clone(),
+                                obligation.recursion_depth + 1,
+                                ty,
+                            )
+                            .value
+                        },
+                        || {},
+                    );
 
-                    // FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
-                    ty::Param(_)
-                    | ty::Projection(..)
-                    | ty::Opaque(..)
-                    | ty::Bound(..)
-                    | ty::Placeholder(..)
-                    | ty::Infer(..)
-                    | ty::Error(_) => {
-                        if tail.has_infer_types() {
-                            candidate_set.mark_ambiguous();
+                    match tail.kind() {
+                        ty::Bool
+                        | ty::Char
+                        | ty::Int(_)
+                        | ty::Uint(_)
+                        | ty::Float(_)
+                        | ty::Str
+                        | ty::Array(..)
+                        | ty::Slice(_)
+                        | ty::RawPtr(..)
+                        | ty::Ref(..)
+                        | ty::FnDef(..)
+                        | ty::FnPtr(..)
+                        | ty::Dynamic(..)
+                        | ty::Closure(..)
+                        | ty::Generator(..)
+                        | ty::GeneratorWitness(..)
+                        | ty::Never
+                        // Extern types have unit metadata, according to RFC 2850
+                        | ty::Foreign(_)
+                        // If returned by `struct_tail_without_normalization` this is a unit struct
+                        // without any fields, or not a struct, and therefore is Sized.
+                        | ty::Adt(..)
+                        // If returned by `struct_tail_without_normalization` this is the empty tuple.
+                        | ty::Tuple(..)
+                        // Integers and floats are always Sized, and so have unit type metadata.
+                        | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
+
+                        // type parameters, opaques, and unnormalized projections have pointer
+                        // metadata if they're known (e.g. by the param_env) to be sized
+                        ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
+                            if selcx.infcx().predicate_must_hold_modulo_regions(
+                                &obligation.with(
+                                    selcx.tcx(),
+                                    ty::Binder::dummy(
+                                        selcx.tcx().at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
+                                    )
+                                    .without_const(),
+                                ),
+                            ) =>
+                        {
+                            true
+                        }
+
+                        // FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
+                        ty::Param(_)
+                        | ty::Projection(..)
+                        | ty::Opaque(..)
+                        | ty::Bound(..)
+                        | ty::Placeholder(..)
+                        | ty::Infer(..)
+                        | ty::Error(_) => {
+                            if tail.has_infer_types() {
+                                candidate_set.mark_ambiguous();
+                            }
+                            false
                         }
-                        false
                     }
+                } else {
+                    bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}")
                 }
             }
             super::ImplSource::Param(..) => {
@@ -1758,7 +1756,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                 false
             }
             super::ImplSource::AutoImpl(..)
-            | super::ImplSource::Builtin(..)
             | super::ImplSource::TraitUpcasting(_)
             | super::ImplSource::ConstDestruct(_) => {
                 // These traits have no associated types.
@@ -1838,14 +1835,10 @@ fn confirm_select_candidate<'cx, 'tcx>(
         super::ImplSource::Future(data) => confirm_future_candidate(selcx, obligation, data),
         super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
         super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
-        super::ImplSource::DiscriminantKind(data) => {
-            confirm_discriminant_kind_candidate(selcx, obligation, data)
-        }
-        super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data),
+        super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
         super::ImplSource::Object(_)
         | super::ImplSource::AutoImpl(..)
         | super::ImplSource::Param(..)
-        | super::ImplSource::Builtin(..)
         | super::ImplSource::TraitUpcasting(_)
         | super::ImplSource::TraitAlias(..)
         | super::ImplSource::ConstDestruct(_) => {
@@ -1951,68 +1944,55 @@ fn confirm_future_candidate<'cx, 'tcx>(
         .with_addl_obligations(obligations)
 }
 
-fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
+fn confirm_builtin_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    _: ImplSourceDiscriminantKindData,
+    data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
-
-    let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
-    // We get here from `poly_project_and_unify_type` which replaces bound vars
-    // with placeholders
-    debug_assert!(!self_ty.has_escaping_bound_vars());
+    let self_ty = obligation.predicate.self_ty();
     let substs = tcx.mk_substs([self_ty.into()].iter());
-
-    let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
-
-    let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
-        term: self_ty.discriminant_ty(tcx).into(),
+    let lang_items = tcx.lang_items();
+    let item_def_id = obligation.predicate.item_def_id;
+    let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
+    let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
+        let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
+        assert_eq!(discriminant_def_id, item_def_id);
+
+        (self_ty.discriminant_ty(tcx).into(), Vec::new())
+    } else if lang_items.pointee_trait() == Some(trait_def_id) {
+        let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
+        assert_eq!(metadata_def_id, item_def_id);
+
+        let mut obligations = Vec::new();
+        let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
+            normalize_with_depth_to(
+                selcx,
+                obligation.param_env,
+                obligation.cause.clone(),
+                obligation.recursion_depth + 1,
+                ty,
+                &mut obligations,
+            )
+        });
+        if check_is_sized {
+            let sized_predicate = ty::Binder::dummy(
+                tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
+            )
+            .without_const();
+            obligations.push(obligation.with(tcx, sized_predicate));
+        }
+        (metadata_ty.into(), obligations)
+    } else {
+        bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
     };
 
-    // We get here from `poly_project_and_unify_type` which replaces bound vars
-    // with placeholders, so dummy is okay here.
-    confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
-}
-
-fn confirm_pointee_candidate<'cx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'tcx>,
-    obligation: &ProjectionTyObligation<'tcx>,
-    _: ImplSourcePointeeData,
-) -> Progress<'tcx> {
-    let tcx = selcx.tcx();
-    let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
-
-    let mut obligations = vec![];
-    let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
-        normalize_with_depth_to(
-            selcx,
-            obligation.param_env,
-            obligation.cause.clone(),
-            obligation.recursion_depth + 1,
-            ty,
-            &mut obligations,
-        )
-    });
-    if check_is_sized {
-        let sized_predicate = ty::Binder::dummy(
-            tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]),
-        )
-        .without_const();
-        obligations.push(obligation.with(tcx, sized_predicate));
-    }
-
-    let substs = tcx.mk_substs([self_ty.into()].iter());
-    let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span));
-
-    let predicate = ty::ProjectionPredicate {
-        projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
-        term: metadata_ty.into(),
-    };
+    let predicate =
+        ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
 
     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
         .with_addl_obligations(obligations)
+        .with_addl_obligations(data.nested)
 }
 
 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 85a125d4c15..f8c7a896b53 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -282,10 +282,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
             } else if lang_items.discriminant_kind_trait() == Some(def_id) {
                 // `DiscriminantKind` is automatically implemented for every type.
-                candidates.vec.push(DiscriminantKindCandidate);
+                candidates.vec.push(BuiltinCandidate { has_nested: false });
             } else if lang_items.pointee_trait() == Some(def_id) {
                 // `Pointee` is automatically implemented for every type.
-                candidates.vec.push(PointeeCandidate);
+                candidates.vec.push(BuiltinCandidate { has_nested: false });
             } else if lang_items.sized_trait() == Some(def_id) {
                 // Sized is never implementable by end-users, it is
                 // always automatically computed.
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 87f44601955..8c589aa8cd1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -22,12 +22,11 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for
 use crate::traits::{
     BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
     ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
-    ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
-    ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
-    ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
-    ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
-    PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
-    Unimplemented, VtblSegment,
+    ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
+    ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
+    ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
+    Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
+    SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment,
 };
 
 use super::BuiltinImplConditions;
@@ -100,12 +99,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::FnPointer(data)
             }
 
-            DiscriminantKindCandidate => {
-                ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
-            }
-
-            PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData),
-
             TraitAliasCandidate => {
                 let data = self.confirm_trait_alias_candidate(obligation);
                 ImplSource::TraitAlias(data)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 189e01da4fd..3c8f8b5642c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1573,20 +1573,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
 
             // (*)
-            (
-                BuiltinCandidate { has_nested: false }
-                | DiscriminantKindCandidate
-                | PointeeCandidate
-                | ConstDestructCandidate(_),
-                _,
-            ) => true,
-            (
-                _,
-                BuiltinCandidate { has_nested: false }
-                | DiscriminantKindCandidate
-                | PointeeCandidate
-                | ConstDestructCandidate(_),
-            ) => false,
+            (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true,
+            (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false,
 
             (ParamCandidate(other), ParamCandidate(victim)) => {
                 let same_except_bound_vars = other.skip_binder().trait_ref
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index a496cea0b00..dae7d589d5c 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -8,7 +8,9 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};
 use rustc_middle::ty::{GenericArg, SubstsRef};
 
-use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
+use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
+use crate::infer::InferCtxtExt;
+use rustc_infer::infer::InferOk;
 pub use rustc_infer::traits::{self, util::*};
 
 ///////////////////////////////////////////////////////////////////////////
@@ -200,13 +202,15 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
 ) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
     let subject = selcx.tcx().bound_impl_subject(impl_def_id);
     let subject = subject.subst(selcx.tcx(), impl_substs);
-    let Normalized { value: subject, obligations: normalization_obligations1 } =
-        super::normalize(selcx, param_env, ObligationCause::dummy(), subject);
+    let InferOk { value: subject, obligations: normalization_obligations1 } = selcx
+        .infcx()
+        .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, subject);
 
     let predicates = selcx.tcx().predicates_of(impl_def_id);
     let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
-    let Normalized { value: predicates, obligations: normalization_obligations2 } =
-        super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
+    let InferOk { value: predicates, obligations: normalization_obligations2 } = selcx
+        .infcx()
+        .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, predicates);
     let impl_obligations =
         super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
 
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 7f16b2d35e8..4a887bc5918 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -270,8 +270,6 @@ fn resolve_associated_item<'tcx>(
         traits::ImplSource::AutoImpl(..)
         | traits::ImplSource::Param(..)
         | traits::ImplSource::TraitAlias(..)
-        | traits::ImplSource::DiscriminantKind(..)
-        | traits::ImplSource::Pointee(..)
         | traits::ImplSource::TraitUpcasting(_)
         | traits::ImplSource::ConstDestruct(_) => None,
     })
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 571396eb835..2c6fd1e1d4d 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -458,7 +458,9 @@ impl Step for Std {
 
         t!(fs::create_dir_all(&out));
 
-        builder.ensure(SharedAssets { target: self.target });
+        if self.format == DocumentationFormat::HTML {
+            builder.ensure(SharedAssets { target: self.target });
+        }
 
         let index_page = builder.src.join("src/doc/index.md").into_os_string();
         let mut extra_args = match self.format {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 38873cee93b..a69979d7f07 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -473,7 +473,7 @@ impl Miri {
         miri: &Path,
         target: TargetSelection,
     ) -> String {
-        let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysrot");
+        let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysroot");
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             compiler,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index c1f7a833834..063082c1c7c 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1139,7 +1139,6 @@ pre.rust .doccomment {
 .example-wrap .tooltip {
 	position: absolute;
 	display: block;
-	cursor: pointer;
 	left: -25px;
 	top: 5px;
 }
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index ff6c6863533..78a0cdcc3bc 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -64,7 +64,7 @@
 	--test-arrow-hover-background-color: #4e8bca;
 	--target-background-color: #fdffd3;
 	--target-border-color: #ad7c37;
-	--tooltip-background-color: #fdffd3;
+	--tooltip-background-color: #000;
 	--tooltip-color: #fff;
 	--kbd-color: #000;
 	--kbd-background: #fafbfc;
diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml
index caa1ab8f31e..4d923be3e78 100644
--- a/src/test/rustdoc-gui/codeblock-tooltip.goml
+++ b/src/test/rustdoc-gui/codeblock-tooltip.goml
@@ -146,7 +146,7 @@ call-function: ("check-colors", {
 })
 call-function: ("check-colors", {
     "theme": "light",
-    "background": "rgb(253, 255, 211)",
+    "background": "rgb(0, 0, 0)",
     "color": "rgb(255, 255, 255)",
     "border": "rgb(224, 224, 224)",
 })
diff --git a/src/test/rustdoc-json/fns/return_type_alias.rs b/src/test/rustdoc-json/fns/return_type_alias.rs
new file mode 100644
index 00000000000..2578bb49ad3
--- /dev/null
+++ b/src/test/rustdoc-json/fns/return_type_alias.rs
@@ -0,0 +1,10 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/104851>
+
+/// @set foo = "$.index[*][?(@.name=='Foo')].id"
+pub type Foo = i32;
+
+// @is "$.index[*][?(@.name=='demo')].inner.decl.output.kind" '"resolved_path"'
+// @is "$.index[*][?(@.name=='demo')].inner.decl.output.inner.id" $foo
+pub fn demo() -> Foo {
+    42
+}
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 225651a997e..a533e367122 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -114,8 +114,8 @@ impl Kind {
     pub fn is_trait(self) -> bool {
         matches!(self, Kind::Trait)
     }
-    pub fn is_struct_enum_union(self) -> bool {
-        matches!(self, Kind::Struct | Kind::Enum | Kind::Union)
+    pub fn is_type(self) -> bool {
+        matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::Typedef)
     }
 
     pub fn from_item(i: &Item) -> Self {
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index 5b293a3c4f7..9548276d826 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -32,7 +32,10 @@ pub struct Validator<'a> {
 
 enum PathKind {
     Trait,
-    StructEnumUnion,
+    /// Structs, Enums, Unions and Typedefs.
+    ///
+    /// This doesn't include trait's because traits are not types.
+    Type,
 }
 
 impl<'a> Validator<'a> {
@@ -224,7 +227,7 @@ impl<'a> Validator<'a> {
 
     fn check_type(&mut self, x: &'a Type) {
         match x {
-            Type::ResolvedPath(path) => self.check_path(path, PathKind::StructEnumUnion),
+            Type::ResolvedPath(path) => self.check_path(path, PathKind::Type),
             Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait),
             Type::Generic(_) => {}
             Type::Primitive(_) => {}
@@ -264,7 +267,7 @@ impl<'a> Validator<'a> {
     fn check_path(&mut self, x: &'a Path, kind: PathKind) {
         match kind {
             PathKind::Trait => self.add_trait_id(&x.id),
-            PathKind::StructEnumUnion => self.add_struct_enum_union_id(&x.id),
+            PathKind::Type => self.add_type_id(&x.id),
         }
         if let Some(args) = &x.args {
             self.check_generic_args(&**args);
@@ -392,8 +395,8 @@ impl<'a> Validator<'a> {
         self.add_id_checked(id, Kind::is_trait, "Trait");
     }
 
-    fn add_struct_enum_union_id(&mut self, id: &'a Id) {
-        self.add_id_checked(id, Kind::is_struct_enum_union, "Struct or Enum or Union");
+    fn add_type_id(&mut self, id: &'a Id) {
+        self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or Typedef)");
     }
 
     /// Add an Id that appeared in a trait