Skip to content

Commit 469a4cc

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 469a4cc

69 files changed

Lines changed: 809 additions & 167 deletions

File tree

Some content is hidden

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

compiler/rustc_ast/src/ast.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3635,6 +3635,7 @@ impl Item {
36353635
| ItemKind::DelegationMac(_)
36363636
| ItemKind::MacroDef(..) => None,
36373637
ItemKind::Static(_) => None,
3638+
ItemKind::AutoImpl(ai) => Some(&ai.generics),
36383639
ItemKind::Const(i) => Some(&i.generics),
36393640
ItemKind::Fn(i) => Some(&i.generics),
36403641
ItemKind::TyAlias(i) => Some(&i.generics),
@@ -3778,6 +3779,14 @@ pub struct Impl {
37783779
pub items: ThinVec<Box<AssocItem>>,
37793780
}
37803781

3782+
#[derive(Clone, Encodable, Decodable, Debug)]
3783+
pub struct AutoImpl {
3784+
pub generics: Generics,
3785+
pub constness: Const,
3786+
pub of_trait: Box<TraitImplHeader>,
3787+
pub items: ThinVec<Box<AssocItem>>,
3788+
}
3789+
37813790
#[derive(Clone, Encodable, Decodable, Debug)]
37823791
pub struct TraitImplHeader {
37833792
pub defaultness: Defaultness,
@@ -3958,6 +3967,8 @@ pub enum ItemKind {
39583967
///
39593968
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
39603969
Impl(Impl),
3970+
/// An `auto impl` implementation, such as a supertrait `auto impl`.
3971+
AutoImpl(Box<AutoImpl>),
39613972
/// A macro invocation.
39623973
///
39633974
/// E.g., `foo!(..)`.
@@ -3994,6 +4005,7 @@ impl ItemKind {
39944005
| ItemKind::ForeignMod(_)
39954006
| ItemKind::GlobalAsm(_)
39964007
| ItemKind::Impl(_)
4008+
| ItemKind::AutoImpl(_)
39974009
| ItemKind::MacCall(_)
39984010
| ItemKind::DelegationMac(_) => None,
39994011
}
@@ -4006,7 +4018,12 @@ impl ItemKind {
40064018
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
40074019
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
40084020
| Delegation(..) | DelegationMac(..) => "a",
4009-
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
4021+
ExternCrate(..)
4022+
| ForeignMod(..)
4023+
| MacCall(..)
4024+
| Enum(..)
4025+
| Impl { .. }
4026+
| AutoImpl { .. } => "an",
40104027
}
40114028
}
40124029

@@ -4029,6 +4046,7 @@ impl ItemKind {
40294046
ItemKind::MacCall(..) => "item macro invocation",
40304047
ItemKind::MacroDef(..) => "macro definition",
40314048
ItemKind::Impl { .. } => "implementation",
4049+
ItemKind::AutoImpl { .. } => "`auto` implementation",
40324050
ItemKind::Delegation(..) => "delegated function",
40334051
ItemKind::DelegationMac(..) => "delegation",
40344052
}
@@ -4076,6 +4094,8 @@ pub enum AssocItemKind {
40764094
Delegation(Box<Delegation>),
40774095
/// An associated list or glob delegation item.
40784096
DelegationMac(Box<DelegationMac>),
4097+
/// An `auto impl` item
4098+
AutoImpl(Box<AutoImpl>),
40794099
}
40804100

40814101
impl AssocItemKind {
@@ -4086,15 +4106,21 @@ impl AssocItemKind {
40864106
| AssocItemKind::Type(box TyAlias { ident, .. })
40874107
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
40884108

4089-
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4109+
AssocItemKind::MacCall(_)
4110+
| AssocItemKind::DelegationMac(_)
4111+
| AssocItemKind::AutoImpl(_) => None,
40904112
}
40914113
}
40924114

40934115
pub fn defaultness(&self) -> Defaultness {
40944116
match *self {
40954117
Self::Const(box ConstItem { defaultness, .. })
40964118
| Self::Fn(box Fn { defaultness, .. })
4097-
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4119+
| Self::Type(box TyAlias { defaultness, .. })
4120+
| Self::AutoImpl(box AutoImpl {
4121+
of_trait: box TraitImplHeader { defaultness, .. },
4122+
..
4123+
}) => defaultness,
40984124
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
40994125
Defaultness::Final
41004126
}
@@ -4111,6 +4137,7 @@ impl From<AssocItemKind> for ItemKind {
41114137
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
41124138
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
41134139
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4140+
AssocItemKind::AutoImpl(ai) => ItemKind::AutoImpl(ai),
41144141
}
41154142
}
41164143
}
@@ -4126,6 +4153,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
41264153
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
41274154
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
41284155
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4156+
ItemKind::AutoImpl(ai) => AssocItemKind::AutoImpl(ai),
41294157
_ => return Err(item_kind),
41304158
})
41314159
}

compiler/rustc_ast/src/visit.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ 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);
560561
fn visit_block(Block);
561562
//fn visit_nested_use_tree((UseTree, NodeId));
562563
fn visit_capture_by(CaptureBy);
@@ -842,6 +843,8 @@ macro_rules! common_visitor_and_walkers {
842843
visit_visitable!($($mut)? vis, ident, generics, variant_data),
843844
ItemKind::Impl(impl_) =>
844845
visit_visitable!($($mut)? vis, impl_),
846+
ItemKind::AutoImpl(auto_impl_) =>
847+
visit_visitable!($($mut)? vis, auto_impl_),
845848
ItemKind::Trait(trait_) =>
846849
visit_visitable!($($mut)? vis, trait_),
847850
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
@@ -887,6 +890,8 @@ macro_rules! common_visitor_and_walkers {
887890
visit_visitable!($($mut)? vis, delegation),
888891
AssocItemKind::DelegationMac(dm) =>
889892
visit_visitable!($($mut)? vis, dm),
893+
AssocItemKind::AutoImpl(ai) =>
894+
visit_visitable!($($mut)? vis, ai),
890895
}
891896
V::Result::output()
892897
}
@@ -951,6 +956,17 @@ macro_rules! common_visitor_and_walkers {
951956
V::Result::output()
952957
});
953958

959+
impl_walkable!(|&$($mut)? $($lt)? self: AutoImpl, vis: &mut V| {
960+
let AutoImpl { generics, of_trait, items, constness } = self;
961+
let TraitImplHeader { defaultness, safety, polarity, trait_ref } = &$($mut)? **of_trait;
962+
963+
try_visit!(vis.visit_generics(generics));
964+
visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref);
965+
966+
visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: true });
967+
V::Result::output()
968+
});
969+
954970
// Special case to call `visit_method_receiver_expr`.
955971
impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| {
956972
let MethodCall { seg, receiver, args, span } = self;

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 66 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,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
215216
| ItemKind::Trait(..)
216217
| ItemKind::TraitAlias(..)
217218
| ItemKind::Impl(..)
219+
| ItemKind::AutoImpl(..)
218220
| ItemKind::MacCall(..)
219221
| ItemKind::MacroDef(..)
220222
| ItemKind::Delegation(..)
@@ -489,6 +491,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
489491
constness,
490492
})
491493
}
494+
ItemKind::AutoImpl(box AutoImpl { .. }) => {
495+
feature_err(
496+
self.tcx.sess,
497+
sym::supertrait_auto_impl,
498+
span,
499+
"feature is under construction",
500+
)
501+
.emit();
502+
FatalError.raise()
503+
}
492504
ItemKind::Trait(box Trait {
493505
constness,
494506
is_auto,
@@ -1009,6 +1021,49 @@ impl<'hir> LoweringContext<'_, 'hir> {
10091021
true,
10101022
)
10111023
}
1024+
AssocItemKind::AutoImpl(ai) => {
1025+
let tcx = self.tcx;
1026+
if !tcx.features().supertrait_auto_impl() {
1027+
feature_err(
1028+
&tcx.sess,
1029+
sym::supertrait_auto_impl,
1030+
i.span,
1031+
"feature is under construction",
1032+
)
1033+
.emit();
1034+
FatalError.raise();
1035+
}
1036+
let generics = tcx.arena.alloc(hir::Generics {
1037+
has_where_clause_predicates: false,
1038+
params: &[],
1039+
predicates: &[],
1040+
where_clause_span: DUMMY_SP,
1041+
span: DUMMY_SP,
1042+
});
1043+
(
1044+
Ident::dummy(),
1045+
&*generics,
1046+
hir::TraitItemKind::AutoImpl(
1047+
tcx.arena.alloc(self.lower_poly_trait_ref_inner(
1048+
&ai.generics.params,
1049+
&TraitBoundModifiers {
1050+
constness: BoundConstness::Never,
1051+
asyncness: BoundAsyncness::Normal,
1052+
polarity: match ai.of_trait.polarity {
1053+
ImplPolarity::Positive => BoundPolarity::Positive,
1054+
ImplPolarity::Negative(span) => BoundPolarity::Negative(span),
1055+
},
1056+
},
1057+
&ai.of_trait.trait_ref,
1058+
ai.of_trait.trait_ref.path.span,
1059+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
1060+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1061+
)),
1062+
&[],
1063+
),
1064+
false,
1065+
)
1066+
}
10121067
AssocItemKind::Type(box TyAlias {
10131068
ident,
10141069
generics,
@@ -1214,6 +1269,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
12141269
),
12151270
)
12161271
}
1272+
AssocItemKind::AutoImpl(_) => {
1273+
feature_err(
1274+
&self.tcx.sess,
1275+
sym::supertrait_auto_impl,
1276+
i.span,
1277+
"feature is under construction",
1278+
)
1279+
.emit();
1280+
FatalError.raise();
1281+
}
12171282
AssocItemKind::Delegation(box delegation) => {
12181283
let delegation_results = self.lower_delegation(delegation, i.id);
12191284
(

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)