Skip to content

Commit 6c33a56

Browse files
committed
Initial support for auto traits with default bounds
1 parent 30f168e commit 6c33a56

26 files changed

+872
-88
lines changed

compiler/rustc_hir/src/lang_items.rs

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

435441
/// 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
@@ -344,9 +344,8 @@ fn bounds_from_generic_predicates<'tcx>(
344344
ty::ClauseKind::Trait(trait_predicate) => {
345345
let entry = types.entry(trait_predicate.self_ty()).or_default();
346346
let def_id = trait_predicate.def_id();
347-
if Some(def_id) != tcx.lang_items().sized_trait() {
348-
// Type params are `Sized` by default, do not add that restriction to the list
349-
// if it is a positive requirement.
347+
if !tcx.is_default_trait(def_id) {
348+
// Do not add that restriction to the list if it is a positive requirement.
350349
entry.push(trait_predicate.def_id());
351350
}
352351
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ fn associated_type_bounds<'tcx>(
3939
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
4040
let mut bounds = Vec::new();
4141
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
42-
// Associated types are implicitly sized unless a `?Sized` bound is found
42+
// Implicit bounds are added to associated types unless a `?Trait` bound is found
4343
match filter {
4444
PredicateFilter::All
4545
| PredicateFilter::SelfOnly
4646
| PredicateFilter::SelfTraitThatDefines(_)
4747
| PredicateFilter::SelfAndAssociatedTypeBounds => {
48-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
48+
icx.lowerer().add_implicit_traits(&mut bounds, item_ty, hir_bounds, None, span);
4949
}
5050
// `ConstIfConst` is only interested in `~const` bounds.
5151
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
@@ -328,14 +328,13 @@ fn opaque_type_bounds<'tcx>(
328328
let icx = ItemCtxt::new(tcx, opaque_def_id);
329329
let mut bounds = Vec::new();
330330
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
331-
// Opaque types are implicitly sized unless a `?Sized` bound is found
331+
// Implicit bounds are added to opaque types unless a `?Trait` bound is found
332332
match filter {
333333
PredicateFilter::All
334334
| PredicateFilter::SelfOnly
335335
| PredicateFilter::SelfTraitThatDefines(_)
336336
| PredicateFilter::SelfAndAssociatedTypeBounds => {
337-
// Associated types are implicitly sized unless a `?Sized` bound is found
338-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
337+
icx.lowerer().add_implicit_traits(&mut bounds, item_ty, hir_bounds, None, span);
339338
}
340339
//`ConstIfConst` is only interested in `~const` bounds.
341340
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

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

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

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

175204
// Below we'll consider the bounds on the type parameters (including `Self`)
@@ -180,11 +209,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
180209
let mut bounds = Vec::new();
181210
icx.lowerer().lower_bounds(
182211
tcx.types.self_param,
183-
self_bounds,
212+
self_bounds.0,
184213
&mut bounds,
185214
ty::List::empty(),
186215
PredicateFilter::All,
187216
);
217+
icx.lowerer().add_implicit_super_traits(
218+
def_id,
219+
&mut bounds,
220+
self_bounds.0,
221+
hir_generics,
222+
self_bounds.1,
223+
);
188224
predicates.extend(bounds);
189225
}
190226

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

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

0 commit comments

Comments
 (0)