about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-12-12 13:20:36 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-12-12 13:20:36 +0000
commit21917b086661ef7b0803280fc0ce753ac130f35f (patch)
tree98cbe479353defed9f871f31e0e327a2ba8c5656
parent8b098325ec26834ec5eb056697b1fd733cca7be9 (diff)
Round 3: require binders for substs
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs1
-rw-r--r--src/librustdoc/clean/mod.rs46
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/clean/utils.rs29
4 files changed, 50 insertions, 28 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 470bfc484bf..25b8d01918b 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -980,6 +980,7 @@ where
     /// contain any bound vars that would be bound by the
     /// binder. This is commonly used to 'inject' a value T into a
     /// different binding level.
+    #[track_caller]
     pub fn dummy(value: T) -> Binder<'tcx, T> {
         assert!(!value.has_escaping_bound_vars());
         Binder(value, ty::List::empty())
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 0174b1a71b5..89c8abe4f99 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -165,7 +165,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
     }
     inline::record_extern_fqn(cx, trait_ref.def_id(), kind);
     let path =
-        external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.skip_binder().substs);
+        external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.substs));
 
     debug!(?trait_ref);
 
@@ -437,7 +437,7 @@ fn clean_projection<'tcx>(
     };
     let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
     Type::QPath(Box::new(QPathData {
-        assoc: projection_to_path_segment(ty.skip_binder(), cx),
+        assoc: projection_to_path_segment(ty, cx),
         should_show_cast,
         self_type,
         trait_,
@@ -452,15 +452,16 @@ fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type
 }
 
 fn projection_to_path_segment<'tcx>(
-    ty: ty::ProjectionTy<'tcx>,
+    ty: ty::Binder<'tcx, ty::ProjectionTy<'tcx>>,
     cx: &mut DocContext<'tcx>,
 ) -> PathSegment {
-    let item = cx.tcx.associated_item(ty.item_def_id);
-    let generics = cx.tcx.generics_of(ty.item_def_id);
+    let item = cx.tcx.associated_item(ty.skip_binder().item_def_id);
+    let generics = cx.tcx.generics_of(ty.skip_binder().item_def_id);
     PathSegment {
         name: item.name,
         args: GenericArgs::AngleBracketed {
-            args: substs_to_args(cx, &ty.substs[generics.parent_count..], false).into(),
+            args: substs_to_args(cx, ty.map_bound(|ty| &ty.substs[generics.parent_count..]), false)
+                .into(),
             bindings: Default::default(),
         },
     }
@@ -1732,12 +1733,18 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 AdtKind::Enum => ItemType::Enum,
             };
             inline::record_extern_fqn(cx, did, kind);
-            let path = external_path(cx, did, false, ThinVec::new(), substs);
+            let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(substs));
             Type::Path { path }
         }
         ty::Foreign(did) => {
             inline::record_extern_fqn(cx, did, ItemType::ForeignType);
-            let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
+            let path = external_path(
+                cx,
+                did,
+                false,
+                ThinVec::new(),
+                ty::Binder::dummy(InternalSubsts::empty()),
+            );
             Type::Path { path }
         }
         ty::Dynamic(obj, ref reg, _) => {
@@ -1750,9 +1757,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 .or_else(|| dids.next())
                 .unwrap_or_else(|| panic!("found trait object `{bound_ty:?}` with no traits?"));
             let substs = match obj.principal() {
-                Some(principal) => principal.skip_binder().substs,
+                Some(principal) => principal.map_bound(|p| p.substs),
                 // marker traits have no substs.
-                _ => cx.tcx.intern_substs(&[]),
+                _ => ty::Binder::dummy(InternalSubsts::empty()),
             };
 
             inline::record_extern_fqn(cx, did, ItemType::Trait);
@@ -1763,7 +1770,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
             let lifetime = clean_middle_region(*reg);
             let mut bounds = dids
                 .map(|did| {
-                    let empty = cx.tcx.intern_substs(&[]);
+                    let empty = ty::Binder::dummy(InternalSubsts::empty());
                     let path = external_path(cx, did, false, ThinVec::new(), empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
                     PolyTrait { trait_: path, generic_params: Vec::new() }
@@ -1774,11 +1781,13 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 .projection_bounds()
                 .map(|pb| TypeBinding {
                     assoc: projection_to_path_segment(
-                        pb.skip_binder()
-                            // HACK(compiler-errors): Doesn't actually matter what self
-                            // type we put here, because we're only using the GAT's substs.
-                            .with_self_ty(cx.tcx, cx.tcx.types.self_param)
-                            .projection_ty,
+                        pb.map_bound(|pb| {
+                            pb
+                                // HACK(compiler-errors): Doesn't actually matter what self
+                                // type we put here, because we're only using the GAT's substs.
+                                .with_self_ty(cx.tcx, cx.tcx.types.self_param)
+                                .projection_ty
+                        }),
                         cx,
                     ),
                     kind: TypeBindingKind::Equality {
@@ -1883,7 +1892,10 @@ fn clean_middle_opaque_bounds<'tcx>(
                     {
                         if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
                             Some(TypeBinding {
-                                assoc: projection_to_path_segment(proj.projection_ty, cx),
+                                assoc: projection_to_path_segment(
+                                    bound.kind().rebind(proj.projection_ty),
+                                    cx,
+                                ),
                                 kind: TypeBindingKind::Equality {
                                     term: clean_middle_term(bound.kind().rebind(proj.term), cx),
                                 },
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 98329e7fc91..7a7313c4bc9 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1343,7 +1343,7 @@ pub(crate) enum GenericBound {
 impl GenericBound {
     pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
-        let empty = cx.tcx.intern_substs(&[]);
+        let empty = ty::Binder::dummy(ty::InternalSubsts::empty());
         let path = external_path(cx, did, false, ThinVec::new(), empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 6c1bc2801d8..a12f764fa8e 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -78,12 +78,16 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
 
 pub(crate) fn substs_to_args<'tcx>(
     cx: &mut DocContext<'tcx>,
-    substs: &[ty::subst::GenericArg<'tcx>],
+    substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
     mut skip_first: bool,
 ) -> Vec<GenericArg> {
     let mut ret_val =
-        Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 }));
-    ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() {
+        Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
+            1
+        } else {
+            0
+        }));
+    ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
         GenericArgKind::Lifetime(lt) => {
             Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
         }
@@ -92,10 +96,10 @@ pub(crate) fn substs_to_args<'tcx>(
             None
         }
         GenericArgKind::Type(ty) => {
-            Some(GenericArg::Type(clean_middle_ty(ty::Binder::dummy(ty), cx, None)))
+            Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
         }
         GenericArgKind::Const(ct) => {
-            Some(GenericArg::Const(Box::new(clean_middle_const(ty::Binder::dummy(ct), cx))))
+            Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
         }
     }));
     ret_val
@@ -106,15 +110,20 @@ fn external_generic_args<'tcx>(
     did: DefId,
     has_self: bool,
     bindings: ThinVec<TypeBinding>,
-    substs: SubstsRef<'tcx>,
+    substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
 ) -> GenericArgs {
-    let args = substs_to_args(cx, substs, has_self);
+    let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
 
     if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
+        let ty = substs
+            .iter()
+            .nth(if has_self { 1 } else { 0 })
+            .unwrap()
+            .map_bound(|arg| arg.expect_ty());
         let inputs =
             // The trait's first substitution is the one after self, if there is one.
-            match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
-                ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty::Binder::dummy(t), cx, None)).collect::<Vec<_>>().into(),
+            match ty.skip_binder().kind() {
+                ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
                 _ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
             };
         let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
@@ -134,7 +143,7 @@ pub(super) fn external_path<'tcx>(
     did: DefId,
     has_self: bool,
     bindings: ThinVec<TypeBinding>,
-    substs: SubstsRef<'tcx>,
+    substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
 ) -> Path {
     let def_kind = cx.tcx.def_kind(did);
     let name = cx.tcx.item_name(did);