Skip to content

Commit a988faa

Browse files
committed
initial implementation for default auto traits
1 parent 28e684b commit a988faa

File tree

60 files changed

+1258
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1258
-200
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,8 +1525,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
15251525
continue;
15261526
}
15271527
let is_param = *is_param.get_or_insert_with(compute_is_param);
1528-
if !is_param {
1529-
self.dcx().emit_err(MisplacedRelaxTraitBound { span: bound.span() });
1528+
if !is_param && !self.tcx.features().more_maybe_bounds {
1529+
self.tcx
1530+
.sess
1531+
.create_feature_err(
1532+
MisplacedRelaxTraitBound { span: bound.span() },
1533+
sym::more_maybe_bounds,
1534+
)
1535+
.emit();
15301536
}
15311537
}
15321538
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12161216
itctx,
12171217
TraitBoundModifiers::NONE,
12181218
);
1219+
let bound = (bound, hir::TraitBoundModifier::None);
12191220
let bounds = this.arena.alloc_from_iter([bound]);
12201221
let lifetime_bound = this.elided_dyn_bound(t.span);
12211222
(bounds, lifetime_bound)
@@ -1348,21 +1349,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13481349
// We can safely ignore constness here since AST validation
13491350
// takes care of rejecting invalid modifier combinations and
13501351
// const trait bounds in trait object types.
1351-
GenericBound::Trait(ty, modifiers) => match modifiers.polarity {
1352-
BoundPolarity::Positive | BoundPolarity::Negative(_) => {
1353-
Some(this.lower_poly_trait_ref(
1354-
ty,
1355-
itctx,
1356-
// Still, don't pass along the constness here; we don't want to
1357-
// synthesize any host effect args, it'd only cause problems.
1358-
TraitBoundModifiers {
1359-
constness: BoundConstness::Never,
1360-
..*modifiers
1361-
},
1362-
))
1363-
}
1364-
BoundPolarity::Maybe(_) => None,
1365-
},
1352+
GenericBound::Trait(ty, modifiers) => {
1353+
// Still, don't pass along the constness here; we don't want to
1354+
// synthesize any host effect args, it'd only cause problems.
1355+
let modifiers = TraitBoundModifiers {
1356+
constness: BoundConstness::Never,
1357+
..*modifiers
1358+
};
1359+
let trait_ref = this.lower_poly_trait_ref(ty, itctx, modifiers);
1360+
let polarity = this.lower_trait_bound_modifiers(modifiers);
1361+
Some((trait_ref, polarity))
1362+
}
13661363
GenericBound::Outlives(lifetime) => {
13671364
if lifetime_bound.is_none() {
13681365
lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2688,6 +2685,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26882685
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
26892686
span: self.lower_span(span),
26902687
};
2688+
let principal = (principal, hir::TraitBoundModifier::None);
26912689

26922690
// The original ID is taken by the `PolyTraitRef`,
26932691
// so the `Ty` itself needs a different one.

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,14 +1345,28 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13451345
match bound {
13461346
GenericBound::Trait(trait_ref, modifiers) => {
13471347
match (ctxt, modifiers.constness, modifiers.polarity) {
1348-
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
1349-
self.dcx().emit_err(errors::OptionalTraitSupertrait {
1350-
span: trait_ref.span,
1351-
path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
1352-
});
1348+
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
1349+
if !self.features.more_maybe_bounds =>
1350+
{
1351+
self.session
1352+
.create_feature_err(
1353+
errors::OptionalTraitSupertrait {
1354+
span: trait_ref.span,
1355+
path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
1356+
},
1357+
sym::more_maybe_bounds,
1358+
)
1359+
.emit();
13531360
}
1354-
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
1355-
self.dcx().emit_err(errors::OptionalTraitObject { span: trait_ref.span });
1361+
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_))
1362+
if !self.features.more_maybe_bounds =>
1363+
{
1364+
self.session
1365+
.create_feature_err(
1366+
errors::OptionalTraitObject { span: trait_ref.span },
1367+
sym::more_maybe_bounds,
1368+
)
1369+
.emit();
13561370
}
13571371
(
13581372
BoundKind::TraitObject,

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ declare_features! (
205205
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
206206
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
207207
(unstable, link_cfg, "1.14.0", None),
208+
/// Allows using `?Trait` trait bounds in more contexts.
209+
(internal, more_maybe_bounds, "CURRENT_RUSTC_VERSION", None),
208210
/// Allows the `multiple_supertrait_upcastable` lint.
209211
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
210212
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!

compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2832,7 +2832,11 @@ pub enum TyKind<'hir> {
28322832
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
28332833
/// A trait object type `Bound1 + Bound2 + Bound3`
28342834
/// where `Bound` is a trait or a lifetime.
2835-
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
2835+
TraitObject(
2836+
&'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
2837+
&'hir Lifetime,
2838+
TraitObjectSyntax,
2839+
),
28362840
/// Unused for now.
28372841
Typeof(&'hir AnonConst),
28382842
/// `TyKind::Infer` means the type should be inferred instead of it having been

compiler/rustc_hir/src/intravisit.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
902902
try_visit!(visitor.visit_array_length(length));
903903
}
904904
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
905-
walk_list!(visitor, visit_poly_trait_ref, bounds);
905+
for (bound, _modifier) in bounds {
906+
try_visit!(visitor.visit_poly_trait_ref(bound));
907+
}
906908
try_visit!(visitor.visit_lifetime(lifetime));
907909
}
908910
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),

compiler/rustc_hir/src/lang_items.rs

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

418424
pub enum GenericRequirement {

compiler/rustc_hir_analysis/src/bounds.rs

Lines changed: 21 additions & 5 deletions
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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,8 @@ fn bounds_from_generic_predicates<'tcx>(
353353
ty::ClauseKind::Trait(trait_predicate) => {
354354
let entry = types.entry(trait_predicate.self_ty()).or_default();
355355
let def_id = trait_predicate.def_id();
356-
if Some(def_id) != tcx.lang_items().sized_trait() {
357-
// Type params are `Sized` by default, do not add that restriction to the list
358-
// if it is a positive requirement.
356+
if !tcx.is_default_trait(def_id) {
357+
// Do not add that restriction to the list if it is a positive requirement.
359358
entry.push(trait_predicate.def_id());
360359
}
361360
}

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
831831

832832
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
833833
match ty.kind {
834-
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
834+
hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments {
835835
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
836836
_ => false,
837837
},

0 commit comments

Comments
 (0)