Skip to content

Commit c19307a

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 5c49c4f commit c19307a

File tree

71 files changed

+938
-176
lines changed

Some content is hidden

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

71 files changed

+938
-176
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3635,6 +3635,8 @@ impl Item {
36353635
| ItemKind::DelegationMac(_)
36363636
| ItemKind::MacroDef(..) => None,
36373637
ItemKind::Static(_) => None,
3638+
ItemKind::AutoImpl(ai) => Some(&ai.generics),
3639+
ItemKind::ExternImpl(ei) => Some(&ei.generics),
36383640
ItemKind::Const(i) => Some(&i.generics),
36393641
ItemKind::Fn(i) => Some(&i.generics),
36403642
ItemKind::TyAlias(i) => Some(&i.generics),
@@ -3778,6 +3780,20 @@ pub struct Impl {
37783780
pub items: ThinVec<Box<AssocItem>>,
37793781
}
37803782

3783+
#[derive(Clone, Encodable, Decodable, Debug)]
3784+
pub struct AutoImpl {
3785+
pub generics: Generics,
3786+
pub constness: Const,
3787+
pub of_trait: Box<TraitImplHeader>,
3788+
pub items: ThinVec<Box<AssocItem>>,
3789+
}
3790+
3791+
#[derive(Clone, Encodable, Decodable, Debug)]
3792+
pub struct ExternImpl {
3793+
pub generics: Generics,
3794+
pub of_trait: Box<TraitImplHeader>,
3795+
}
3796+
37813797
#[derive(Clone, Encodable, Decodable, Debug)]
37823798
pub struct TraitImplHeader {
37833799
pub defaultness: Defaultness,
@@ -3958,6 +3974,10 @@ pub enum ItemKind {
39583974
///
39593975
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
39603976
Impl(Impl),
3977+
/// An `auto impl` implementation, such as a supertrait `auto impl`.
3978+
AutoImpl(Box<AutoImpl>),
3979+
/// An `extern impl` directive
3980+
ExternImpl(Box<ExternImpl>),
39613981
/// A macro invocation.
39623982
///
39633983
/// E.g., `foo!(..)`.
@@ -3994,6 +4014,8 @@ impl ItemKind {
39944014
| ItemKind::ForeignMod(_)
39954015
| ItemKind::GlobalAsm(_)
39964016
| ItemKind::Impl(_)
4017+
| ItemKind::AutoImpl(_)
4018+
| ItemKind::ExternImpl(_)
39974019
| ItemKind::MacCall(_)
39984020
| ItemKind::DelegationMac(_) => None,
39994021
}
@@ -4006,7 +4028,13 @@ impl ItemKind {
40064028
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
40074029
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
40084030
| Delegation(..) | DelegationMac(..) => "a",
4009-
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
4031+
ExternCrate(..)
4032+
| ForeignMod(..)
4033+
| MacCall(..)
4034+
| Enum(..)
4035+
| Impl { .. }
4036+
| AutoImpl(..)
4037+
| ExternImpl(..) => "an",
40104038
}
40114039
}
40124040

@@ -4029,6 +4057,8 @@ impl ItemKind {
40294057
ItemKind::MacCall(..) => "item macro invocation",
40304058
ItemKind::MacroDef(..) => "macro definition",
40314059
ItemKind::Impl { .. } => "implementation",
4060+
ItemKind::AutoImpl { .. } => "`auto` implementation",
4061+
ItemKind::ExternImpl { .. } => "`extern` implementation",
40324062
ItemKind::Delegation(..) => "delegated function",
40334063
ItemKind::DelegationMac(..) => "delegation",
40344064
}
@@ -4076,6 +4106,8 @@ pub enum AssocItemKind {
40764106
Delegation(Box<Delegation>),
40774107
/// An associated list or glob delegation item.
40784108
DelegationMac(Box<DelegationMac>),
4109+
/// An `auto impl` item
4110+
AutoImpl(Box<AutoImpl>),
40794111
}
40804112

40814113
impl AssocItemKind {
@@ -4086,15 +4118,21 @@ impl AssocItemKind {
40864118
| AssocItemKind::Type(box TyAlias { ident, .. })
40874119
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
40884120

4089-
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4121+
AssocItemKind::MacCall(_)
4122+
| AssocItemKind::DelegationMac(_)
4123+
| AssocItemKind::AutoImpl(_) => None,
40904124
}
40914125
}
40924126

40934127
pub fn defaultness(&self) -> Defaultness {
40944128
match *self {
40954129
Self::Const(box ConstItem { defaultness, .. })
40964130
| Self::Fn(box Fn { defaultness, .. })
4097-
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4131+
| Self::Type(box TyAlias { defaultness, .. })
4132+
| Self::AutoImpl(box AutoImpl {
4133+
of_trait: box TraitImplHeader { defaultness, .. },
4134+
..
4135+
}) => defaultness,
40984136
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
40994137
Defaultness::Final
41004138
}
@@ -4111,6 +4149,7 @@ impl From<AssocItemKind> for ItemKind {
41114149
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
41124150
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
41134151
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4152+
AssocItemKind::AutoImpl(ai) => ItemKind::AutoImpl(ai),
41144153
}
41154154
}
41164155
}
@@ -4126,6 +4165,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
41264165
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
41274166
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
41284167
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4168+
ItemKind::AutoImpl(ai) => AssocItemKind::AutoImpl(ai),
41294169
_ => return Err(item_kind),
41304170
})
41314171
}

compiler/rustc_ast/src/visit.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,8 @@ macro_rules! common_visitor_and_walkers {
557557
//fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt);
558558
fn visit_assoc_item_constraint(AssocItemConstraint);
559559
fn visit_attribute(Attribute);
560+
fn visit_auto_impl(AutoImpl);
561+
fn visit_extern_impl(ExternImpl);
560562
fn visit_block(Block);
561563
//fn visit_nested_use_tree((UseTree, NodeId));
562564
fn visit_capture_by(CaptureBy);
@@ -842,6 +844,10 @@ macro_rules! common_visitor_and_walkers {
842844
visit_visitable!($($mut)? vis, ident, generics, variant_data),
843845
ItemKind::Impl(impl_) =>
844846
visit_visitable!($($mut)? vis, impl_),
847+
ItemKind::AutoImpl(auto_impl_) =>
848+
visit_visitable!($($mut)? vis, auto_impl_),
849+
ItemKind::ExternImpl(extern_impl_) =>
850+
visit_visitable!($($mut)? vis, extern_impl_),
845851
ItemKind::Trait(trait_) =>
846852
visit_visitable!($($mut)? vis, trait_),
847853
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
@@ -887,6 +893,8 @@ macro_rules! common_visitor_and_walkers {
887893
visit_visitable!($($mut)? vis, delegation),
888894
AssocItemKind::DelegationMac(dm) =>
889895
visit_visitable!($($mut)? vis, dm),
896+
AssocItemKind::AutoImpl(ai) =>
897+
visit_visitable!($($mut)? vis, ai),
890898
}
891899
V::Result::output()
892900
}
@@ -951,6 +959,27 @@ macro_rules! common_visitor_and_walkers {
951959
V::Result::output()
952960
});
953961

962+
impl_walkable!(|&$($mut)? $($lt)? self: AutoImpl, vis: &mut V| {
963+
let AutoImpl { generics, of_trait, items, constness } = self;
964+
let TraitImplHeader { defaultness, safety, polarity, trait_ref } = &$($mut)? **of_trait;
965+
966+
try_visit!(vis.visit_generics(generics));
967+
visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref);
968+
969+
visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: true });
970+
V::Result::output()
971+
});
972+
973+
impl_walkable!(|&$($mut)? $($lt)? self: ExternImpl, vis: &mut V| {
974+
let ExternImpl { generics, of_trait } = self;
975+
let TraitImplHeader { defaultness, safety, polarity, trait_ref } = &$($mut)? **of_trait;
976+
977+
try_visit!(vis.visit_generics(generics));
978+
visit_visitable!($($mut)? vis, defaultness, safety, polarity, trait_ref);
979+
980+
V::Result::output()
981+
});
982+
954983
// Special case to call `visit_method_receiver_expr`.
955984
impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| {
956985
let MethodCall { seg, receiver, args, span } = self;

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_abi::ExternAbi;
22
use rustc_ast::visit::AssocCtxt;
33
use rustc_ast::*;
4-
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
4+
use rustc_errors::{E0570, ErrorGuaranteed, FatalError, struct_span_code_err};
55
use rustc_hir::attrs::{AttributeKind, EiiImplResolution};
66
use rustc_hir::def::{DefKind, PerNS, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
@@ -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::def_id::DefId;
1516
use rustc_span::edit_distance::find_best_match_for_name;
1617
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
@@ -215,6 +216,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
215216
| ItemKind::Trait(..)
216217
| ItemKind::TraitAlias(..)
217218
| ItemKind::Impl(..)
219+
| ItemKind::AutoImpl(..)
220+
| ItemKind::ExternImpl(..)
218221
| ItemKind::MacCall(..)
219222
| ItemKind::MacroDef(..)
220223
| ItemKind::Delegation(..)
@@ -489,6 +492,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
489492
constness,
490493
})
491494
}
495+
ItemKind::AutoImpl(..) | ItemKind::ExternImpl(..) => {
496+
feature_err(
497+
self.tcx.sess,
498+
sym::supertrait_auto_impl,
499+
span,
500+
"feature is under construction",
501+
)
502+
.emit();
503+
FatalError.raise()
504+
}
492505
ItemKind::Trait(box Trait {
493506
constness,
494507
is_auto,
@@ -1009,6 +1022,49 @@ impl<'hir> LoweringContext<'_, 'hir> {
10091022
true,
10101023
)
10111024
}
1025+
AssocItemKind::AutoImpl(ai) => {
1026+
let tcx = self.tcx;
1027+
if !tcx.features().supertrait_auto_impl() {
1028+
feature_err(
1029+
&tcx.sess,
1030+
sym::supertrait_auto_impl,
1031+
i.span,
1032+
"feature is under construction",
1033+
)
1034+
.emit();
1035+
FatalError.raise();
1036+
}
1037+
let generics = tcx.arena.alloc(hir::Generics {
1038+
has_where_clause_predicates: false,
1039+
params: &[],
1040+
predicates: &[],
1041+
where_clause_span: DUMMY_SP,
1042+
span: DUMMY_SP,
1043+
});
1044+
(
1045+
Ident::dummy(),
1046+
&*generics,
1047+
hir::TraitItemKind::AutoImpl(
1048+
tcx.arena.alloc(self.lower_poly_trait_ref_inner(
1049+
&ai.generics.params,
1050+
&TraitBoundModifiers {
1051+
constness: BoundConstness::Never,
1052+
asyncness: BoundAsyncness::Normal,
1053+
polarity: match ai.of_trait.polarity {
1054+
ImplPolarity::Positive => BoundPolarity::Positive,
1055+
ImplPolarity::Negative(span) => BoundPolarity::Negative(span),
1056+
},
1057+
},
1058+
&ai.of_trait.trait_ref,
1059+
ai.of_trait.trait_ref.path.span,
1060+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
1061+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1062+
)),
1063+
&[],
1064+
),
1065+
false,
1066+
)
1067+
}
10121068
AssocItemKind::Type(box TyAlias {
10131069
ident,
10141070
generics,
@@ -1214,6 +1270,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
12141270
),
12151271
)
12161272
}
1273+
AssocItemKind::AutoImpl(_) => {
1274+
feature_err(
1275+
&self.tcx.sess,
1276+
sym::supertrait_auto_impl,
1277+
i.span,
1278+
"feature is under construction",
1279+
)
1280+
.emit();
1281+
FatalError.raise();
1282+
}
12171283
AssocItemKind::Delegation(box delegation) => {
12181284
let delegation_results = self.lower_delegation(delegation, i.id);
12191285
(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,21 +2110,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21102110
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
21112111
rbp: RelaxedBoundPolicy<'_>,
21122112
itctx: ImplTraitContext,
2113+
) -> hir::PolyTraitRef<'hir> {
2114+
self.lower_poly_trait_ref_inner(
2115+
bound_generic_params,
2116+
modifiers,
2117+
trait_ref,
2118+
*span,
2119+
rbp,
2120+
itctx,
2121+
)
2122+
}
2123+
2124+
#[instrument(level = "debug", skip(self))]
2125+
fn lower_poly_trait_ref_inner(
2126+
&mut self,
2127+
bound_generic_params: &[GenericParam],
2128+
modifiers: &TraitBoundModifiers,
2129+
trait_ref: &TraitRef,
2130+
span: Span,
2131+
rbp: RelaxedBoundPolicy<'_>,
2132+
itctx: ImplTraitContext,
21132133
) -> hir::PolyTraitRef<'hir> {
21142134
let bound_generic_params =
21152135
self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
21162136
let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
21172137
let modifiers = self.lower_trait_bound_modifiers(*modifiers);
21182138

21192139
if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2120-
self.validate_relaxed_bound(trait_ref, *span, rbp);
2140+
self.validate_relaxed_bound(trait_ref, span, rbp);
21212141
}
21222142

21232143
hir::PolyTraitRef {
21242144
bound_generic_params,
21252145
modifiers,
21262146
trait_ref,
2127-
span: self.lower_span(*span),
2147+
span: self.lower_span(span),
21282148
}
21292149
}
21302150

compiler/rustc_ast_passes/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ ast_passes_auto_generic = auto traits cannot have generic parameters
5050
.label = auto trait cannot have generic parameters
5151
.suggestion = remove the parameters
5252
53+
ast_passes_auto_impl_outside_trait_or_impl_trait =
54+
`auto impl` is outside a `trait` block or trait-`impl` block
55+
5356
ast_passes_auto_items = auto traits cannot have associated items
5457
.label = {ast_passes_auto_items}
5558
.suggestion = remove the associated items

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14201420
}
14211421
visit::walk_item(self, item);
14221422
}
1423+
1424+
ItemKind::AutoImpl(..) => {
1425+
self.dcx().emit_err(errors::AutoImplOutsideTraitOrImplTrait { span: item.span });
1426+
}
1427+
14231428
_ => visit::walk_item(self, item),
14241429
}
14251430

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,13 @@ pub(crate) struct NestedImplTrait {
491491
pub inner: Span,
492492
}
493493

494+
#[derive(Diagnostic)]
495+
#[diag(ast_passes_auto_impl_outside_trait_or_impl_trait)]
496+
pub(crate) struct AutoImplOutsideTraitOrImplTrait {
497+
#[primary_span]
498+
pub(crate) span: Span,
499+
}
500+
494501
#[derive(Diagnostic)]
495502
#[diag(ast_passes_at_least_one_trait)]
496503
pub(crate) struct AtLeastOneTrait {

0 commit comments

Comments
 (0)