Skip to content

Commit a22ccdd

Browse files
committed
Initial support for auto traits with default bounds
1 parent a7fc463 commit a22ccdd

File tree

24 files changed

+849
-85
lines changed

24 files changed

+849
-85
lines changed

compiler/rustc_hir/src/lang_items.rs

+6
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,12 @@ language_item_table! {
434434
// Experimental lang items for implementing contract pre- and post-condition checking.
435435
ContractBuildCheckEnsures, sym::contract_build_check_ensures, contract_build_check_ensures_fn, Target::Fn, GenericRequirement::None;
436436
ContractCheckRequires, sym::contract_check_requires, contract_check_requires_fn, Target::Fn, GenericRequirement::None;
437+
438+
// Experimental lang items for `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727)
439+
DefaultTrait4, sym::default_trait4, default_trait4_trait, Target::Trait, GenericRequirement::None;
440+
DefaultTrait3, sym::default_trait3, default_trait3_trait, Target::Trait, GenericRequirement::None;
441+
DefaultTrait2, sym::default_trait2, default_trait2_trait, Target::Trait, GenericRequirement::None;
442+
DefaultTrait1, sym::default_trait1, default_trait1_trait, Target::Trait, GenericRequirement::None;
437443
}
438444

439445
/// The requirement imposed on the generics of a lang item

compiler/rustc_hir_analysis/src/check/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,8 @@ fn bounds_from_generic_predicates<'tcx>(
341341
ty::ClauseKind::Trait(trait_predicate) => {
342342
let entry = types.entry(trait_predicate.self_ty()).or_default();
343343
let def_id = trait_predicate.def_id();
344-
if Some(def_id) != tcx.lang_items().sized_trait() {
345-
// Type params are `Sized` by default, do not add that restriction to the list
346-
// if it is a positive requirement.
344+
if !tcx.is_default_trait(def_id) {
345+
// Do not add that restriction to the list if it is a positive requirement.
347346
entry.push(trait_predicate.def_id());
348347
}
349348
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ fn associated_type_bounds<'tcx>(
3838
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
3939
let mut bounds = Vec::new();
4040
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
41-
// Associated types are implicitly sized unless a `?Sized` bound is found
41+
// Implicit bounds are added to associated types unless a `?Trait` bound is found
4242
match filter {
4343
PredicateFilter::All
4444
| PredicateFilter::SelfOnly
4545
| PredicateFilter::SelfTraitThatDefines(_)
4646
| PredicateFilter::SelfAndAssociatedTypeBounds => {
47-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
47+
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
4848
}
4949
// `ConstIfConst` is only interested in `~const` bounds.
5050
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
@@ -327,14 +327,13 @@ fn opaque_type_bounds<'tcx>(
327327
let icx = ItemCtxt::new(tcx, opaque_def_id);
328328
let mut bounds = Vec::new();
329329
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
330-
// Opaque types are implicitly sized unless a `?Sized` bound is found
330+
// Implicit bounds are added to opaque types unless a `?Trait` bound is found
331331
match filter {
332332
PredicateFilter::All
333333
| PredicateFilter::SelfOnly
334334
| PredicateFilter::SelfTraitThatDefines(_)
335335
| PredicateFilter::SelfAndAssociatedTypeBounds => {
336-
// Associated types are implicitly sized unless a `?Sized` bound is found
337-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
336+
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
338337
}
339338
//`ConstIfConst` is only interested in `~const` bounds.
340339
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+56-4
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,41 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
165165

166166
ItemKind::Trait(_, _, _, _, self_bounds, ..)
167167
| ItemKind::TraitAlias(_, _, self_bounds) => {
168-
is_trait = Some(self_bounds);
168+
is_trait = Some((self_bounds, item.span));
169169
}
170170
_ => {}
171171
}
172172
};
173173

174+
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.
187+
// See comment on `requires_default_supertraits` for more details.
188+
if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
189+
let mut bounds = Vec::new();
190+
let self_ty_where_predicates = (parent, item.generics.predicates);
191+
icx.lowerer().add_default_traits_with_filter(
192+
&mut bounds,
193+
tcx.types.self_param,
194+
&[],
195+
Some(self_ty_where_predicates),
196+
item.span,
197+
|tr| tr != hir::LangItem::Sized,
198+
);
199+
predicates.extend(bounds);
200+
}
201+
}
202+
174203
let generics = tcx.generics_of(def_id);
175204

176205
// 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
181210
let mut bounds = Vec::new();
182211
icx.lowerer().lower_bounds(
183212
tcx.types.self_param,
184-
self_bounds,
213+
self_bounds.0,
185214
&mut bounds,
186215
ty::List::empty(),
187216
PredicateFilter::All,
188217
);
218+
icx.lowerer().add_default_super_traits(
219+
def_id,
220+
&mut bounds,
221+
self_bounds.0,
222+
hir_generics,
223+
self_bounds.1,
224+
);
189225
predicates.extend(bounds);
190226
}
191227

@@ -210,8 +246,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
210246
GenericParamKind::Type { .. } => {
211247
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
212248
let mut bounds = Vec::new();
213-
// Params are implicitly sized unless a `?Sized` bound is found
214-
icx.lowerer().add_sized_bound(
249+
// Implicit bounds are added to type params unless a `?Trait` bound is found
250+
icx.lowerer().add_default_traits(
215251
&mut bounds,
216252
param_ty,
217253
&[],
@@ -625,6 +661,22 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
625661
let self_param_ty = tcx.types.self_param;
626662
let mut bounds = Vec::new();
627663
icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
664+
match filter {
665+
PredicateFilter::All
666+
| PredicateFilter::SelfOnly
667+
| PredicateFilter::SelfTraitThatDefines(_)
668+
| PredicateFilter::SelfAndAssociatedTypeBounds => {
669+
icx.lowerer().add_default_super_traits(
670+
trait_def_id,
671+
&mut bounds,
672+
superbounds,
673+
generics,
674+
item.span,
675+
);
676+
}
677+
//`ConstIfConst` is only interested in `~const` bounds.
678+
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
679+
}
628680

629681
let where_bounds_that_match =
630682
icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);

0 commit comments

Comments
 (0)