@@ -43,12 +43,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
4343 }
4444
4545 /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
46- /// or associative items.
46+ /// or associated items.
4747 ///
4848 /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
4949 /// should be added everywhere, including super bounds. However this causes a huge performance
5050 /// costs. For optimization purposes instead of adding default supertraits, bounds
51- /// are added to the associative items:
51+ /// are added to the associated items:
5252 ///
5353 /// ```ignore(illustrative)
5454 /// // Default bounds are generated in the following way:
@@ -81,7 +81,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8181 ///
8282 /// Therefore, `experimental_default_bounds` are still being added to supertraits if
8383 /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
84- pub(crate) fn requires_default_supertraits(
84+ fn requires_default_supertraits(
8585 &self,
8686 hir_bounds: &'tcx [hir::GenericBound<'tcx>],
8787 hir_generics: &'tcx hir::Generics<'tcx>,
@@ -120,6 +120,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
120120 found
121121 }
122122
123+ /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
124+ /// they are not added as super trait bounds to the trait itself. See
125+ /// `requires_default_supertraits` for more information.
126+ pub(crate) fn add_default_trait_item_bounds(
127+ &self,
128+ trait_item: &hir::TraitItem<'tcx>,
129+ bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
130+ ) {
131+ let tcx = self.tcx();
132+ if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
133+ return;
134+ }
135+
136+ let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
137+ let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
138+ unreachable!();
139+ };
140+
141+ let (trait_generics, trait_bounds) = match parent_trait.kind {
142+ hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
143+ hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
144+ _ => unreachable!(),
145+ };
146+
147+ if !self.requires_default_supertraits(trait_bounds, trait_generics) {
148+ let self_ty_where_predicates = (parent, trait_item.generics.predicates);
149+ self.add_default_traits_with_filter(
150+ bounds,
151+ tcx.types.self_param,
152+ &[],
153+ Some(self_ty_where_predicates),
154+ trait_item.span,
155+ |tr| tr != hir::LangItem::Sized,
156+ );
157+ }
158+ }
159+
123160 /// Lazily sets `experimental_default_bounds` to true on trait super bounds.
124161 /// See `requires_default_supertraits` for more information.
125162 pub(crate) fn add_default_super_traits(
@@ -130,6 +167,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
130167 hir_generics: &'tcx hir::Generics<'tcx>,
131168 span: Span,
132169 ) {
170+ if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
171+ return;
172+ }
173+
133174 assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
134175 if self.requires_default_supertraits(hir_bounds, hir_generics) {
135176 let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
@@ -263,11 +304,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
263304 seen_unbound = true;
264305 }
265306 let emit_relax_err = || {
266- let unbound_traits =
267- match self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
268- true => "`?Sized` and `experimental_default_bounds`",
269- false => "`?Sized`",
270- };
307+ let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
308+ true => "`?Sized` and `experimental_default_bounds`",
309+ false => "`?Sized`",
310+ };
271311 // There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
272312 tcx.dcx().span_err(
273313 unbound.span,
0 commit comments