Skip to content

Commit fac5797

Browse files
auto-impl: parser support
This patch introduce AST elements for `auto impl` inside the `trait` and `impl` block. This patch does not handle the name resolution, yet. It will be handled in the next patch series. Signed-off-by: Xiangfei Ding <dingxiangfei2009@protonmail.ch>
1 parent 80d8f29 commit fac5797

File tree

77 files changed

+826
-145
lines changed

Some content is hidden

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

77 files changed

+826
-145
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3562,6 +3562,7 @@ impl Item {
35623562
| ItemKind::DelegationMac(_)
35633563
| ItemKind::MacroDef(..) => None,
35643564
ItemKind::Static(_) => None,
3565+
ItemKind::AutoImpl(_) => None,
35653566
ItemKind::Const(i) => Some(&i.generics),
35663567
ItemKind::Fn(i) => Some(&i.generics),
35673568
ItemKind::TyAlias(i) => Some(&i.generics),
@@ -3705,6 +3706,14 @@ pub struct Impl {
37053706
pub items: ThinVec<Box<AssocItem>>,
37063707
}
37073708

3709+
#[derive(Clone, Encodable, Decodable, Debug)]
3710+
pub struct AutoImpl {
3711+
pub generics: Generics,
3712+
pub constness: Const,
3713+
pub of_trait: Box<TraitImplHeader>,
3714+
pub items: ThinVec<Box<AssocItem>>,
3715+
}
3716+
37083717
#[derive(Clone, Encodable, Decodable, Debug)]
37093718
pub struct TraitImplHeader {
37103719
pub defaultness: Defaultness,
@@ -3857,6 +3866,8 @@ pub enum ItemKind {
38573866
///
38583867
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
38593868
Impl(Impl),
3869+
/// An `auto impl` implementation, such as a supertrait `auto impl`.
3870+
AutoImpl(Box<AutoImpl>),
38603871
/// A macro invocation.
38613872
///
38623873
/// E.g., `foo!(..)`.
@@ -3893,6 +3904,7 @@ impl ItemKind {
38933904
| ItemKind::ForeignMod(_)
38943905
| ItemKind::GlobalAsm(_)
38953906
| ItemKind::Impl(_)
3907+
| ItemKind::AutoImpl(_)
38963908
| ItemKind::MacCall(_)
38973909
| ItemKind::DelegationMac(_) => None,
38983910
}
@@ -3905,7 +3917,12 @@ impl ItemKind {
39053917
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
39063918
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
39073919
| Delegation(..) | DelegationMac(..) => "a",
3908-
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3920+
ExternCrate(..)
3921+
| ForeignMod(..)
3922+
| MacCall(..)
3923+
| Enum(..)
3924+
| Impl { .. }
3925+
| AutoImpl { .. } => "an",
39093926
}
39103927
}
39113928

@@ -3928,6 +3945,7 @@ impl ItemKind {
39283945
ItemKind::MacCall(..) => "item macro invocation",
39293946
ItemKind::MacroDef(..) => "macro definition",
39303947
ItemKind::Impl { .. } => "implementation",
3948+
ItemKind::AutoImpl { .. } => "`auto` implementation",
39313949
ItemKind::Delegation(..) => "delegated function",
39323950
ItemKind::DelegationMac(..) => "delegation",
39333951
}
@@ -3975,6 +3993,8 @@ pub enum AssocItemKind {
39753993
Delegation(Box<Delegation>),
39763994
/// An associated list or glob delegation item.
39773995
DelegationMac(Box<DelegationMac>),
3996+
/// An `auto impl` item
3997+
AutoImpl(Box<AutoImpl>),
39783998
}
39793999

39804000
impl AssocItemKind {
@@ -3985,15 +4005,21 @@ impl AssocItemKind {
39854005
| AssocItemKind::Type(box TyAlias { ident, .. })
39864006
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
39874007

3988-
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4008+
AssocItemKind::MacCall(_)
4009+
| AssocItemKind::DelegationMac(_)
4010+
| AssocItemKind::AutoImpl(_) => None,
39894011
}
39904012
}
39914013

39924014
pub fn defaultness(&self) -> Defaultness {
39934015
match *self {
39944016
Self::Const(box ConstItem { defaultness, .. })
39954017
| Self::Fn(box Fn { defaultness, .. })
3996-
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4018+
| Self::Type(box TyAlias { defaultness, .. })
4019+
| Self::AutoImpl(box AutoImpl {
4020+
of_trait: box TraitImplHeader { defaultness, .. },
4021+
..
4022+
}) => defaultness,
39974023
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
39984024
Defaultness::Final
39994025
}
@@ -4010,6 +4036,7 @@ impl From<AssocItemKind> for ItemKind {
40104036
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
40114037
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
40124038
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4039+
AssocItemKind::AutoImpl(ai) => ItemKind::AutoImpl(ai),
40134040
}
40144041
}
40154042
}
@@ -4025,6 +4052,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
40254052
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
40264053
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
40274054
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4055+
ItemKind::AutoImpl(ai) => AssocItemKind::AutoImpl(ai),
40284056
_ => return Err(item_kind),
40294057
})
40304058
}

compiler/rustc_ast/src/visit.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ macro_rules! common_visitor_and_walkers {
551551
//fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt);
552552
fn visit_assoc_item_constraint(AssocItemConstraint);
553553
fn visit_attribute(Attribute);
554+
fn visit_auto_impl(AutoImpl);
554555
fn visit_block(Block);
555556
//fn visit_nested_use_tree((UseTree, NodeId));
556557
fn visit_capture_by(CaptureBy);
@@ -836,6 +837,8 @@ macro_rules! common_visitor_and_walkers {
836837
visit_visitable!($($mut)? vis, ident, generics, variant_data),
837838
ItemKind::Impl(impl_) =>
838839
visit_visitable!($($mut)? vis, impl_),
840+
ItemKind::AutoImpl(auto_impl_) =>
841+
visit_visitable!($($mut)? vis, auto_impl_),
839842
ItemKind::Trait(trait_) =>
840843
visit_visitable!($($mut)? vis, trait_),
841844
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
@@ -881,6 +884,8 @@ macro_rules! common_visitor_and_walkers {
881884
visit_visitable!($($mut)? vis, delegation),
882885
AssocItemKind::DelegationMac(dm) =>
883886
visit_visitable!($($mut)? vis, dm),
887+
AssocItemKind::AutoImpl(ai) =>
888+
visit_visitable!($($mut)? vis, ai),
884889
}
885890
V::Result::output()
886891
}
@@ -945,6 +950,17 @@ macro_rules! common_visitor_and_walkers {
945950
V::Result::output()
946951
});
947952

953+
impl_walkable!(|&$($mut)? $($lt)? self: AutoImpl, vis: &mut V| {
954+
let AutoImpl { generics, of_trait, items, constness } = self;
955+
let TraitImplHeader { defaultness, safety, polarity, trait_ref } = &$($mut)? **of_trait;
956+
957+
try_visit!(vis.visit_generics(generics));
958+
visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref);
959+
960+
visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: true });
961+
V::Result::output()
962+
});
963+
948964
// Special case to call `visit_method_receiver_expr`.
949965
impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| {
950966
let MethodCall { seg, receiver, args, span } = self;

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_hir::{
1111
use rustc_index::{IndexSlice, IndexVec};
1212
use rustc_middle::span_bug;
1313
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
14+
use rustc_session::parse::feature_err;
1415
use rustc_span::edit_distance::find_best_match_for_name;
1516
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
1617
use smallvec::{SmallVec, smallvec};
@@ -388,6 +389,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
388389
constness,
389390
})
390391
}
392+
ItemKind::AutoImpl(box AutoImpl { .. }) => todo!("we should implement lowering to HIR"),
391393
ItemKind::Trait(box Trait {
392394
constness,
393395
is_auto,
@@ -887,6 +889,48 @@ impl<'hir> LoweringContext<'_, 'hir> {
887889
true,
888890
)
889891
}
892+
AssocItemKind::AutoImpl(ai) => {
893+
let tcx = self.tcx;
894+
if !tcx.features().supertrait_auto_impl() {
895+
feature_err(
896+
&tcx.sess,
897+
sym::supertrait_auto_impl,
898+
i.span,
899+
"feature is under construction",
900+
)
901+
.emit();
902+
}
903+
let generics = tcx.arena.alloc(hir::Generics {
904+
has_where_clause_predicates: false,
905+
params: &[],
906+
predicates: &[],
907+
where_clause_span: DUMMY_SP,
908+
span: DUMMY_SP,
909+
});
910+
(
911+
Ident::dummy(),
912+
&*generics,
913+
hir::TraitItemKind::AutoImpl(
914+
tcx.arena.alloc(self.lower_poly_trait_ref_inner(
915+
&ai.generics.params,
916+
&TraitBoundModifiers {
917+
constness: BoundConstness::Never,
918+
asyncness: BoundAsyncness::Normal,
919+
polarity: match ai.of_trait.polarity {
920+
ImplPolarity::Positive => BoundPolarity::Positive,
921+
ImplPolarity::Negative(span) => BoundPolarity::Negative(span),
922+
},
923+
},
924+
&ai.of_trait.trait_ref,
925+
ai.of_trait.trait_ref.path.span,
926+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
927+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
928+
)),
929+
&[],
930+
),
931+
false,
932+
)
933+
}
890934
AssocItemKind::Type(box TyAlias {
891935
ident,
892936
generics,
@@ -1090,6 +1134,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10901134
),
10911135
)
10921136
}
1137+
AssocItemKind::AutoImpl(_) => todo!(),
10931138
AssocItemKind::Delegation(box delegation) => {
10941139
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
10951140
(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,21 +2074,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20742074
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
20752075
rbp: RelaxedBoundPolicy<'_>,
20762076
itctx: ImplTraitContext,
2077+
) -> hir::PolyTraitRef<'hir> {
2078+
self.lower_poly_trait_ref_inner(
2079+
bound_generic_params,
2080+
modifiers,
2081+
trait_ref,
2082+
*span,
2083+
rbp,
2084+
itctx,
2085+
)
2086+
}
2087+
2088+
#[instrument(level = "debug", skip(self))]
2089+
fn lower_poly_trait_ref_inner(
2090+
&mut self,
2091+
bound_generic_params: &[GenericParam],
2092+
modifiers: &TraitBoundModifiers,
2093+
trait_ref: &TraitRef,
2094+
span: Span,
2095+
rbp: RelaxedBoundPolicy<'_>,
2096+
itctx: ImplTraitContext,
20772097
) -> hir::PolyTraitRef<'hir> {
20782098
let bound_generic_params =
20792099
self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
20802100
let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
20812101
let modifiers = self.lower_trait_bound_modifiers(*modifiers);
20822102

20832103
if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2084-
self.validate_relaxed_bound(trait_ref, *span, rbp);
2104+
self.validate_relaxed_bound(trait_ref, span, rbp);
20852105
}
20862106

20872107
hir::PolyTraitRef {
20882108
bound_generic_params,
20892109
modifiers,
20902110
trait_ref,
2091-
span: self.lower_span(*span),
2111+
span: self.lower_span(span),
20922112
}
20932113
}
20942114

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use ast::StaticItem;
22
use itertools::{Itertools, Position};
33
use rustc_ast::{self as ast, ModKind, TraitAlias};
4-
use rustc_span::Ident;
4+
use rustc_span::{Ident, Span};
55

66
use crate::pp::BoxMarker;
77
use crate::pp::Breaks::Inconsistent;
@@ -350,6 +350,32 @@ impl<'a> State<'a> {
350350
let empty = item.attrs.is_empty() && items.is_empty();
351351
self.bclose(item.span, empty, cb);
352352
}
353+
ast::ItemKind::AutoImpl(box ast::AutoImpl { generics, of_trait, items, constness }) => {
354+
let (cb, ib) = self.head("");
355+
self.print_visibility(&item.vis);
356+
357+
let &ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } =
358+
&**of_trait;
359+
self.print_defaultness(defaultness);
360+
self.print_safety(safety);
361+
self.word("auto");
362+
self.word("impl");
363+
self.print_generic_params(&generics.params);
364+
self.print_constness(*constness);
365+
if let ast::ImplPolarity::Negative(_) = polarity {
366+
self.word("!");
367+
}
368+
self.print_trait_ref(trait_ref);
369+
370+
self.space();
371+
self.bopen(ib);
372+
self.print_inner_attributes(&item.attrs);
373+
for impl_item in items {
374+
self.print_assoc_item(impl_item);
375+
}
376+
let empty = item.attrs.is_empty() && items.is_empty();
377+
self.bclose(item.span, empty, cb);
378+
}
353379
ast::ItemKind::Trait(box ast::Trait {
354380
constness,
355381
safety,
@@ -601,6 +627,9 @@ impl<'a> State<'a> {
601627
self.word(";");
602628
}
603629
}
630+
ast::AssocItemKind::AutoImpl(ai) => {
631+
self.print_assoc_auto_impl(&item.attrs, ai, item.span)
632+
}
604633
ast::AssocItemKind::Delegation(deleg) => self.print_delegation(
605634
&item.attrs,
606635
vis,
@@ -621,6 +650,29 @@ impl<'a> State<'a> {
621650
self.ann.post(self, AnnNode::SubItem(id))
622651
}
623652

653+
fn print_assoc_auto_impl(&mut self, attrs: &[ast::Attribute], ai: &ast::AutoImpl, span: Span) {
654+
let (cb, ib) = self.head("");
655+
let &ast::TraitImplHeader { defaultness, safety, polarity, ref trait_ref } = &*ai.of_trait;
656+
self.print_defaultness(defaultness);
657+
self.print_safety(safety);
658+
self.word("auto");
659+
self.word("impl");
660+
self.print_constness(ai.constness);
661+
if let ast::ImplPolarity::Negative(_) = polarity {
662+
self.word("!");
663+
}
664+
self.print_trait_ref(trait_ref);
665+
666+
self.space();
667+
self.bopen(ib);
668+
self.print_inner_attributes(&attrs);
669+
for impl_item in &ai.items {
670+
self.print_assoc_item(impl_item);
671+
}
672+
let empty = attrs.is_empty() && ai.items.is_empty();
673+
self.bclose(span, empty, cb);
674+
}
675+
624676
fn print_delegation(
625677
&mut self,
626678
attrs: &[ast::Attribute],

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,8 @@ declare_features! (
647647
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
648648
/// Allows `super let` statements.
649649
(unstable, super_let, "1.88.0", Some(139076)),
650+
/// Allows supertraits to be implemented with automatic defaults
651+
(unstable, supertrait_auto_impl, "CURRENT_RUSTC_VERSION", Some(99999)),
650652
/// Allows subtrait items to shadow supertrait items.
651653
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
652654
/// Allows the use of target_feature when a function is marked inline(always).

0 commit comments

Comments
 (0)