Skip to content

Commit 5bb36db

Browse files
committed
initial implementation for default auto traits
1 parent fdf61d4 commit 5bb36db

28 files changed

+931
-113
lines changed

compiler/rustc_hir/src/lang_items.rs

+6
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ language_item_table! {
414414
EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None;
415415
EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1);
416416
EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1);
417+
418+
// Experimental lang items for `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727)
419+
DefaultTrait4, sym::default_trait4, default_trait4_trait, Target::Trait, GenericRequirement::None;
420+
DefaultTrait3, sym::default_trait3, default_trait3_trait, Target::Trait, GenericRequirement::None;
421+
DefaultTrait2, sym::default_trait2, default_trait2_trait, Target::Trait, GenericRequirement::None;
422+
DefaultTrait1, sym::default_trait1, default_trait1_trait, Target::Trait, GenericRequirement::None;
417423
}
418424

419425
pub enum GenericRequirement {

compiler/rustc_hir_analysis/src/bounds.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,27 @@ impl<'tcx> Bounds<'tcx> {
166166
));
167167
}
168168

169-
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
170-
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
171-
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
172-
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
173-
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
169+
pub fn push_lang_item_trait(
170+
&mut self,
171+
tcx: TyCtxt<'tcx>,
172+
ty: Ty<'tcx>,
173+
lang_item: LangItem,
174+
span: Span,
175+
) {
176+
assert_eq!(lang_item.target(), rustc_hir::Target::Trait);
177+
if lang_item == LangItem::Sized {
178+
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
179+
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
180+
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
181+
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
182+
} else {
183+
// Do not generate default bounds if lang item was not defined
184+
let Some(trait_def_id) = tcx.lang_items().get(lang_item) else {
185+
return;
186+
};
187+
let trait_ref = ty::TraitRef::new(tcx, trait_def_id, [ty]);
188+
self.clauses.push((trait_ref.upcast(tcx), span));
189+
}
174190
}
175191

176192
pub fn clauses(

compiler/rustc_hir_analysis/src/check/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,8 @@ fn bounds_from_generic_predicates<'tcx>(
349349
ty::ClauseKind::Trait(trait_predicate) => {
350350
let entry = types.entry(trait_predicate.self_ty()).or_default();
351351
let def_id = trait_predicate.def_id();
352-
if Some(def_id) != tcx.lang_items().sized_trait() {
353-
// Type params are `Sized` by default, do not add that restriction to the list
354-
// if it is a positive requirement.
352+
if !tcx.is_default_trait(def_id) {
353+
// Do not add that restriction to the list if it is a positive requirement.
355354
entry.push(trait_predicate.def_id());
356355
}
357356
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ fn associated_type_bounds<'tcx>(
3434

3535
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
3636
let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
37-
// Associated types are implicitly sized unless a `?Sized` bound is found
38-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
37+
// Implicit bounds are added to associated types unless a `?Trait` bound is found
38+
icx.lowerer().add_implicit_traits(&mut bounds, item_ty, hir_bounds, None, span);
3939

4040
let trait_def_id = tcx.local_parent(assoc_item_def_id);
4141
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
@@ -74,8 +74,8 @@ fn opaque_type_bounds<'tcx>(
7474
ty::print::with_reduced_queries!({
7575
let icx = ItemCtxt::new(tcx, opaque_def_id);
7676
let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter);
77-
// Opaque types are implicitly sized unless a `?Sized` bound is found
78-
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
77+
// Implicit bounds are added to opaque types unless a `?Trait` bound is found
78+
icx.lowerer().add_implicit_traits(&mut bounds, item_ty, hir_bounds, None, span);
7979
debug!(?bounds);
8080

8181
tcx.arena.alloc_from_iter(bounds.clauses(tcx))

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+48-6
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
144144
}
145145

146146
ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => {
147-
is_trait = Some(self_bounds);
147+
is_trait = Some((self_bounds, item.span));
148148
}
149149

150150
ItemKind::Fn(sig, _, _) => {
@@ -159,6 +159,34 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
159159
_ => {}
160160
}
161161
};
162+
if let Node::TraitItem(item) = node {
163+
let parent = tcx.local_parent(item.hir_id().owner.def_id);
164+
let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
165+
unreachable!();
166+
};
167+
168+
let (trait_generics, trait_bounds) = match parent_trait.kind {
169+
hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
170+
hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
171+
_ => unreachable!(),
172+
};
173+
174+
// Implicitly add `Self: Trait` clauses on trait associated items.
175+
// See comment on `add_implicit_super_traits` for more details.
176+
if !icx.lowerer().requires_implicit_supertraits(parent, trait_bounds, trait_generics) {
177+
let mut bounds = Bounds::default();
178+
let self_ty_where_predicates = (parent, item.generics.predicates);
179+
icx.lowerer().add_implicit_traits_with_filter(
180+
&mut bounds,
181+
tcx.types.self_param,
182+
&[],
183+
Some(self_ty_where_predicates),
184+
item.span,
185+
|tr| tr != hir::LangItem::Sized,
186+
);
187+
predicates.extend(bounds.clauses(tcx));
188+
}
189+
}
162190

163191
let generics = tcx.generics_of(def_id);
164192

@@ -167,11 +195,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
167195
// on a trait we must also consider the bounds that follow the trait's name,
168196
// like `trait Foo: A + B + C`.
169197
if let Some(self_bounds) = is_trait {
170-
let bounds = icx.lowerer().lower_mono_bounds(
198+
let mut bounds = icx.lowerer().lower_mono_bounds(
171199
tcx.types.self_param,
172-
self_bounds,
200+
self_bounds.0,
173201
PredicateFilter::All,
174202
);
203+
icx.lowerer().add_implicit_super_traits(
204+
def_id,
205+
&mut bounds,
206+
self_bounds.0,
207+
hir_generics,
208+
self_bounds.1,
209+
);
175210
predicates.extend(bounds.clauses(tcx));
176211
effects_min_tys.extend(bounds.effects_min_tys());
177212
}
@@ -197,8 +232,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
197232
GenericParamKind::Type { .. } => {
198233
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
199234
let mut bounds = Bounds::default();
200-
// Params are implicitly sized unless a `?Sized` bound is found
201-
icx.lowerer().add_sized_bound(
235+
// Implicit bounds are added to type params unless a `?Trait` bound is found
236+
icx.lowerer().add_implicit_traits(
202237
&mut bounds,
203238
param_ty,
204239
&[],
@@ -620,7 +655,14 @@ pub(super) fn implied_predicates_with_filter(
620655
let icx = ItemCtxt::new(tcx, trait_def_id);
621656

622657
let self_param_ty = tcx.types.self_param;
623-
let superbounds = icx.lowerer().lower_mono_bounds(self_param_ty, bounds, filter);
658+
let mut superbounds = icx.lowerer().lower_mono_bounds(self_param_ty, bounds, filter);
659+
icx.lowerer().add_implicit_super_traits(
660+
trait_def_id,
661+
&mut superbounds,
662+
bounds,
663+
generics,
664+
item.span,
665+
);
624666

625667
let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
626668
generics,

0 commit comments

Comments
 (0)