-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial support for auto traits with default bounds #120706
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,12 +165,41 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen | |
|
||
ItemKind::Trait(_, _, _, _, self_bounds, ..) | ||
| ItemKind::TraitAlias(_, _, self_bounds) => { | ||
is_trait = Some(self_bounds); | ||
is_trait = Some((self_bounds, item.span)); | ||
} | ||
_ => {} | ||
} | ||
}; | ||
|
||
if let Node::TraitItem(item) = node { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do not put this in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not clear to me. From what I see Perhaps you were confused by the |
||
let parent = tcx.local_parent(item.hir_id().owner.def_id); | ||
let 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!(), | ||
}; | ||
|
||
// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items. | ||
// 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); | ||
|
||
// Below we'll consider the bounds on the type parameters (including `Self`) | ||
|
@@ -181,11 +210,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen | |
let mut bounds = Vec::new(); | ||
icx.lowerer().lower_bounds( | ||
tcx.types.self_param, | ||
self_bounds, | ||
self_bounds.0, | ||
&mut bounds, | ||
ty::List::empty(), | ||
PredicateFilter::All, | ||
); | ||
icx.lowerer().add_default_super_traits( | ||
def_id, | ||
&mut bounds, | ||
self_bounds.0, | ||
hir_generics, | ||
self_bounds.1, | ||
); | ||
predicates.extend(bounds); | ||
} | ||
|
||
|
@@ -210,8 +246,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen | |
GenericParamKind::Type { .. } => { | ||
let param_ty = icx.lowerer().lower_ty_param(param.hir_id); | ||
let mut bounds = Vec::new(); | ||
// Params are implicitly sized unless a `?Sized` bound is found | ||
icx.lowerer().add_sized_bound( | ||
// Implicit bounds are added to type params unless a `?Trait` bound is found | ||
icx.lowerer().add_default_traits( | ||
&mut bounds, | ||
param_ty, | ||
&[], | ||
|
@@ -625,6 +661,22 @@ pub(super) fn implied_predicates_with_filter<'tcx>( | |
let self_param_ty = tcx.types.self_param; | ||
let mut bounds = Vec::new(); | ||
icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); | ||
match filter { | ||
PredicateFilter::All | ||
| PredicateFilter::SelfOnly | ||
| PredicateFilter::SelfTraitThatDefines(_) | ||
| PredicateFilter::SelfAndAssociatedTypeBounds => { | ||
icx.lowerer().add_default_super_traits( | ||
trait_def_id, | ||
&mut bounds, | ||
superbounds, | ||
generics, | ||
item.span, | ||
); | ||
} | ||
//`ConstIfConst` is only interested in `~const` bounds. | ||
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} | ||
} | ||
|
||
let where_bounds_that_match = | ||
icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not make it so that the compiler collects these traits on-demand, rather than having to be hard-coded in the compiler? Having 4 dummy lang items is kinda annoying, and it seems like something that can be an attr on a trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can. This would require partially copying the logic for lang items collection, as new traits can be defined in another crate. Using lang items is just easier.