Skip to content

Commit b1bfd4c

Browse files
committed
Initial support for auto traits with default bounds
1 parent 79de6c0 commit b1bfd4c

File tree

24 files changed

+852
-86
lines changed

24 files changed

+852
-86
lines changed

compiler/rustc_hir/src/lang_items.rs

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

438444
/// 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

+57-4
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,42 @@ 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 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+
}
202+
}
203+
174204
let generics = tcx.generics_of(def_id);
175205

176206
// Below we'll consider the bounds on the type parameters (including `Self`)
@@ -181,11 +211,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
181211
let mut bounds = Vec::new();
182212
icx.lowerer().lower_bounds(
183213
tcx.types.self_param,
184-
self_bounds,
214+
self_bounds.0,
185215
&mut bounds,
186216
ty::List::empty(),
187217
PredicateFilter::All,
188218
);
219+
icx.lowerer().add_default_super_traits(
220+
def_id,
221+
&mut bounds,
222+
self_bounds.0,
223+
hir_generics,
224+
self_bounds.1,
225+
);
189226
predicates.extend(bounds);
190227
}
191228

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

629682
let where_bounds_that_match =
630683
icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);

0 commit comments

Comments
 (0)