Skip to content

Commit 0522ed0

Browse files
committed
Default auto traits: fix perf
1 parent f174fd7 commit 0522ed0

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+3-27
Original file line numberDiff line numberDiff line change
@@ -172,33 +172,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
172172
};
173173

174174
if let Node::TraitItem(item) = node {
175-
let parent = tcx.local_parent(item.hir_id().owner.def_id);
176-
let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
177-
unreachable!();
178-
};
179-
180-
let (trait_generics, trait_bounds) = match parent_trait.kind {
181-
hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
182-
hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
183-
_ => unreachable!(),
184-
};
185-
186-
// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
187-
// they are not added as super trait bounds to the trait itself. See comment on
188-
// `requires_default_supertraits` for more details.
189-
if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
190-
let mut bounds = Vec::new();
191-
let self_ty_where_predicates = (parent, item.generics.predicates);
192-
icx.lowerer().add_default_traits_with_filter(
193-
&mut bounds,
194-
tcx.types.self_param,
195-
&[],
196-
Some(self_ty_where_predicates),
197-
item.span,
198-
|tr| tr != hir::LangItem::Sized,
199-
);
200-
predicates.extend(bounds);
201-
}
175+
let mut bounds = Vec::new();
176+
icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
177+
predicates.extend(bounds);
202178
}
203179

204180
let generics = tcx.generics_of(def_id);

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+48-8
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)