Rollup merge of #139365 - Bryanskiy:leak-perf, r=lcnr
Default auto traits: fix perf Skip computing `requires_default_supertraits` if `experimental-default-bounds` option is not enabled. Possible perf fix for https://github.com/rust-lang/rust/pull/120706 r? lcnr
This commit is contained in:
commit
f4c429fde5
2 changed files with 51 additions and 35 deletions
|
@ -172,33 +172,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Node::TraitItem(item) = node {
|
if let Node::TraitItem(item) = node {
|
||||||
let parent = tcx.local_parent(item.hir_id().owner.def_id);
|
let mut bounds = Vec::new();
|
||||||
let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
|
icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
|
||||||
unreachable!();
|
predicates.extend(bounds);
|
||||||
};
|
|
||||||
|
|
||||||
let (trait_generics, trait_bounds) = match parent_trait.kind {
|
|
||||||
hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
|
|
||||||
hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
|
|
||||||
// they are not added as super trait bounds to the trait itself. See comment on
|
|
||||||
// `requires_default_supertraits` for more details.
|
|
||||||
if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
|
|
||||||
let mut bounds = Vec::new();
|
|
||||||
let self_ty_where_predicates = (parent, item.generics.predicates);
|
|
||||||
icx.lowerer().add_default_traits_with_filter(
|
|
||||||
&mut bounds,
|
|
||||||
tcx.types.self_param,
|
|
||||||
&[],
|
|
||||||
Some(self_ty_where_predicates),
|
|
||||||
item.span,
|
|
||||||
|tr| tr != hir::LangItem::Sized,
|
|
||||||
);
|
|
||||||
predicates.extend(bounds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
|
|
|
@ -43,12 +43,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
|
/// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
|
||||||
/// or associative items.
|
/// or associated items.
|
||||||
///
|
///
|
||||||
/// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
|
/// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
|
||||||
/// should be added everywhere, including super bounds. However this causes a huge performance
|
/// should be added everywhere, including super bounds. However this causes a huge performance
|
||||||
/// costs. For optimization purposes instead of adding default supertraits, bounds
|
/// costs. For optimization purposes instead of adding default supertraits, bounds
|
||||||
/// are added to the associative items:
|
/// are added to the associated items:
|
||||||
///
|
///
|
||||||
/// ```ignore(illustrative)
|
/// ```ignore(illustrative)
|
||||||
/// // Default bounds are generated in the following way:
|
/// // Default bounds are generated in the following way:
|
||||||
|
@ -81,7 +81,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
///
|
///
|
||||||
/// Therefore, `experimental_default_bounds` are still being added to supertraits if
|
/// Therefore, `experimental_default_bounds` are still being added to supertraits if
|
||||||
/// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
|
/// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
|
||||||
pub(crate) fn requires_default_supertraits(
|
fn requires_default_supertraits(
|
||||||
&self,
|
&self,
|
||||||
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
|
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
hir_generics: &'tcx hir::Generics<'tcx>,
|
hir_generics: &'tcx hir::Generics<'tcx>,
|
||||||
|
@ -120,6 +120,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
found
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
|
||||||
|
/// they are not added as super trait bounds to the trait itself. See
|
||||||
|
/// `requires_default_supertraits` for more information.
|
||||||
|
pub(crate) fn add_default_trait_item_bounds(
|
||||||
|
&self,
|
||||||
|
trait_item: &hir::TraitItem<'tcx>,
|
||||||
|
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
|
) {
|
||||||
|
let tcx = self.tcx();
|
||||||
|
if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
|
||||||
|
let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
let (trait_generics, trait_bounds) = match parent_trait.kind {
|
||||||
|
hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
|
||||||
|
hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !self.requires_default_supertraits(trait_bounds, trait_generics) {
|
||||||
|
let self_ty_where_predicates = (parent, trait_item.generics.predicates);
|
||||||
|
self.add_default_traits_with_filter(
|
||||||
|
bounds,
|
||||||
|
tcx.types.self_param,
|
||||||
|
&[],
|
||||||
|
Some(self_ty_where_predicates),
|
||||||
|
trait_item.span,
|
||||||
|
|tr| tr != hir::LangItem::Sized,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Lazily sets `experimental_default_bounds` to true on trait super bounds.
|
/// Lazily sets `experimental_default_bounds` to true on trait super bounds.
|
||||||
/// See `requires_default_supertraits` for more information.
|
/// See `requires_default_supertraits` for more information.
|
||||||
pub(crate) fn add_default_super_traits(
|
pub(crate) fn add_default_super_traits(
|
||||||
|
@ -130,6 +167,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
hir_generics: &'tcx hir::Generics<'tcx>,
|
hir_generics: &'tcx hir::Generics<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
|
if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
|
assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
|
||||||
if self.requires_default_supertraits(hir_bounds, hir_generics) {
|
if self.requires_default_supertraits(hir_bounds, hir_generics) {
|
||||||
let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
|
let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
|
||||||
|
@ -263,11 +304,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
seen_unbound = true;
|
seen_unbound = true;
|
||||||
}
|
}
|
||||||
let emit_relax_err = || {
|
let emit_relax_err = || {
|
||||||
let unbound_traits =
|
let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
|
||||||
match self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
|
true => "`?Sized` and `experimental_default_bounds`",
|
||||||
true => "`?Sized` and `experimental_default_bounds`",
|
false => "`?Sized`",
|
||||||
false => "`?Sized`",
|
};
|
||||||
};
|
|
||||||
// There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
|
// There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
|
||||||
tcx.dcx().span_err(
|
tcx.dcx().span_err(
|
||||||
unbound.span,
|
unbound.span,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue