Skip to content

Commit ed73c51

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 38c7129 commit ed73c51

73 files changed

Lines changed: 1223 additions & 194 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: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3636,6 +3636,8 @@ impl Item {
36363636
| ItemKind::DelegationMac(_)
36373637
| ItemKind::MacroDef(..) => None,
36383638
ItemKind::Static(_) => None,
3639+
ItemKind::AutoImpl(ai) => Some(&ai.generics),
3640+
ItemKind::ExternImpl(ei) => Some(&ei.generics),
36393641
ItemKind::Const(i) => Some(&i.generics),
36403642
ItemKind::Fn(i) => Some(&i.generics),
36413643
ItemKind::TyAlias(i) => Some(&i.generics),
@@ -3779,6 +3781,20 @@ pub struct Impl {
37793781
pub items: ThinVec<Box<AssocItem>>,
37803782
}
37813783

3784+
#[derive(Clone, Encodable, Decodable, Debug)]
3785+
pub struct AutoImpl {
3786+
pub generics: Generics,
3787+
pub constness: Const,
3788+
pub of_trait: Box<TraitImplHeader>,
3789+
pub items: ThinVec<Box<AssocItem>>,
3790+
}
3791+
3792+
#[derive(Clone, Encodable, Decodable, Debug)]
3793+
pub struct ExternImpl {
3794+
pub generics: Generics,
3795+
pub of_trait: Box<TraitImplHeader>,
3796+
}
3797+
37823798
#[derive(Clone, Encodable, Decodable, Debug)]
37833799
pub struct TraitImplHeader {
37843800
pub defaultness: Defaultness,
@@ -3975,6 +3991,10 @@ pub enum ItemKind {
39753991
///
39763992
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
39773993
Impl(Impl),
3994+
/// An `auto impl` implementation, such as a supertrait `auto impl`.
3995+
AutoImpl(Box<AutoImpl>),
3996+
/// An `extern impl` directive
3997+
ExternImpl(Box<ExternImpl>),
39783998
/// A macro invocation.
39793999
///
39804000
/// E.g., `foo!(..)`.
@@ -4013,6 +4033,8 @@ impl ItemKind {
40134033
| ItemKind::ForeignMod(_)
40144034
| ItemKind::GlobalAsm(_)
40154035
| ItemKind::Impl(_)
4036+
| ItemKind::AutoImpl(_)
4037+
| ItemKind::ExternImpl(_)
40164038
| ItemKind::MacCall(_)
40174039
| ItemKind::DelegationMac(_) => None,
40184040
}
@@ -4025,7 +4047,13 @@ impl ItemKind {
40254047
Use(..) | Static(..) | Const(..) | ConstBlock(..) | Fn(..) | Mod(..)
40264048
| GlobalAsm(..) | TyAlias(..) | Struct(..) | Union(..) | Trait(..) | TraitAlias(..)
40274049
| MacroDef(..) | Delegation(..) | DelegationMac(..) => "a",
4028-
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
4050+
ExternCrate(..)
4051+
| ForeignMod(..)
4052+
| MacCall(..)
4053+
| Enum(..)
4054+
| Impl { .. }
4055+
| AutoImpl(..)
4056+
| ExternImpl(..) => "an",
40294057
}
40304058
}
40314059

@@ -4049,6 +4077,8 @@ impl ItemKind {
40494077
ItemKind::MacCall(..) => "item macro invocation",
40504078
ItemKind::MacroDef(..) => "macro definition",
40514079
ItemKind::Impl { .. } => "implementation",
4080+
ItemKind::AutoImpl { .. } => "`auto` implementation",
4081+
ItemKind::ExternImpl { .. } => "`extern` implementation",
40524082
ItemKind::Delegation(..) => "delegated function",
40534083
ItemKind::DelegationMac(..) => "delegation",
40544084
}
@@ -4064,6 +4094,8 @@ impl ItemKind {
40644094
| Self::Union(_, generics, _)
40654095
| Self::Trait(box Trait { generics, .. })
40664096
| Self::TraitAlias(box TraitAlias { generics, .. })
4097+
| Self::AutoImpl(box AutoImpl { generics, .. })
4098+
| Self::ExternImpl(box ExternImpl { generics, .. })
40674099
| Self::Impl(Impl { generics, .. }) => Some(generics),
40684100

40694101
Self::ExternCrate(..)
@@ -4107,6 +4139,10 @@ pub enum AssocItemKind {
41074139
Delegation(Box<Delegation>),
41084140
/// An associated list or glob delegation item.
41094141
DelegationMac(Box<DelegationMac>),
4142+
/// An `auto impl` item
4143+
AutoImpl(Box<AutoImpl>),
4144+
/// An `extern impl` item
4145+
ExternImpl(Box<ExternImpl>),
41104146
}
41114147

41124148
impl AssocItemKind {
@@ -4117,15 +4153,26 @@ impl AssocItemKind {
41174153
| AssocItemKind::Type(box TyAlias { ident, .. })
41184154
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
41194155

4120-
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4156+
AssocItemKind::MacCall(_)
4157+
| AssocItemKind::DelegationMac(_)
4158+
| AssocItemKind::AutoImpl(_)
4159+
| AssocItemKind::ExternImpl(_) => None,
41214160
}
41224161
}
41234162

41244163
pub fn defaultness(&self) -> Defaultness {
41254164
match *self {
41264165
Self::Const(box ConstItem { defaultness, .. })
41274166
| Self::Fn(box Fn { defaultness, .. })
4128-
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4167+
| Self::Type(box TyAlias { defaultness, .. })
4168+
| Self::AutoImpl(box AutoImpl {
4169+
of_trait: box TraitImplHeader { defaultness, .. },
4170+
..
4171+
})
4172+
| Self::ExternImpl(box ExternImpl {
4173+
of_trait: box TraitImplHeader { defaultness, .. },
4174+
..
4175+
}) => defaultness,
41294176
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
41304177
Defaultness::Final
41314178
}
@@ -4142,6 +4189,8 @@ impl From<AssocItemKind> for ItemKind {
41424189
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
41434190
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
41444191
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4192+
AssocItemKind::AutoImpl(ai) => ItemKind::AutoImpl(ai),
4193+
AssocItemKind::ExternImpl(ei) => ItemKind::ExternImpl(ei),
41454194
}
41464195
}
41474196
}
@@ -4157,6 +4206,8 @@ impl TryFrom<ItemKind> for AssocItemKind {
41574206
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
41584207
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
41594208
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4209+
ItemKind::AutoImpl(ai) => AssocItemKind::AutoImpl(ai),
4210+
ItemKind::ExternImpl(ei) => AssocItemKind::ExternImpl(ei),
41604211
_ => return Err(item_kind),
41614212
})
41624213
}

compiler/rustc_ast/src/visit.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ macro_rules! common_visitor_and_walkers {
558558
//fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt);
559559
fn visit_assoc_item_constraint(AssocItemConstraint);
560560
fn visit_attribute(Attribute);
561+
fn visit_auto_impl(AutoImpl);
562+
fn visit_extern_impl(ExternImpl);
561563
fn visit_block(Block);
562564
//fn visit_nested_use_tree((UseTree, NodeId));
563565
fn visit_capture_by(CaptureBy);
@@ -845,6 +847,10 @@ macro_rules! common_visitor_and_walkers {
845847
visit_visitable!($($mut)? vis, ident, generics, variant_data),
846848
ItemKind::Impl(impl_) =>
847849
visit_visitable!($($mut)? vis, impl_),
850+
ItemKind::AutoImpl(auto_impl_) =>
851+
visit_visitable!($($mut)? vis, auto_impl_),
852+
ItemKind::ExternImpl(extern_impl_) =>
853+
visit_visitable!($($mut)? vis, extern_impl_),
848854
ItemKind::Trait(trait_) =>
849855
visit_visitable!($($mut)? vis, trait_),
850856
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
@@ -890,6 +896,10 @@ macro_rules! common_visitor_and_walkers {
890896
visit_visitable!($($mut)? vis, delegation),
891897
AssocItemKind::DelegationMac(dm) =>
892898
visit_visitable!($($mut)? vis, dm),
899+
AssocItemKind::AutoImpl(ai) =>
900+
visit_visitable!($($mut)? vis, ai),
901+
AssocItemKind::ExternImpl(ei) =>
902+
visit_visitable!($($mut)? vis, ei),
893903
}
894904
V::Result::output()
895905
}
@@ -954,6 +964,27 @@ macro_rules! common_visitor_and_walkers {
954964
V::Result::output()
955965
});
956966

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

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 74 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};
@@ -89,6 +90,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8990
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
9091
}
9192
AstOwner::AssocItem(item, ctxt) => {
93+
if matches!(item.kind, AssocItemKind::ExternImpl(_)) {
94+
// We do not lower `extern unsafe? impl` items.
95+
// They just discharge the `auto impl` obligation from the current
96+
// `impl` block.
97+
return;
98+
}
9299
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
93100
}
94101
AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
@@ -216,6 +223,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
216223
| ItemKind::Trait(..)
217224
| ItemKind::TraitAlias(..)
218225
| ItemKind::Impl(..)
226+
| ItemKind::AutoImpl(..)
227+
| ItemKind::ExternImpl(..)
219228
| ItemKind::MacCall(..)
220229
| ItemKind::MacroDef(..)
221230
| ItemKind::Delegation(..)
@@ -508,6 +517,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
508517
constness,
509518
})
510519
}
520+
ItemKind::AutoImpl(..) | ItemKind::ExternImpl(..) => {
521+
feature_err(
522+
self.tcx.sess,
523+
sym::supertrait_auto_impl,
524+
span,
525+
"feature is under construction",
526+
)
527+
.emit();
528+
FatalError.raise()
529+
}
511530
ItemKind::Trait(box Trait {
512531
constness,
513532
is_auto,
@@ -1028,6 +1047,50 @@ impl<'hir> LoweringContext<'_, 'hir> {
10281047
true,
10291048
)
10301049
}
1050+
AssocItemKind::AutoImpl(ai) => {
1051+
let tcx = self.tcx;
1052+
if !tcx.features().supertrait_auto_impl() {
1053+
feature_err(
1054+
&tcx.sess,
1055+
sym::supertrait_auto_impl,
1056+
i.span,
1057+
"feature is under construction",
1058+
)
1059+
.emit();
1060+
FatalError.raise();
1061+
}
1062+
let generics = tcx.arena.alloc(hir::Generics {
1063+
has_where_clause_predicates: false,
1064+
params: &[],
1065+
predicates: &[],
1066+
where_clause_span: DUMMY_SP,
1067+
span: DUMMY_SP,
1068+
});
1069+
(
1070+
Ident::dummy(),
1071+
&*generics,
1072+
hir::TraitItemKind::AutoImpl(
1073+
tcx.arena.alloc(self.lower_poly_trait_ref_inner(
1074+
&ai.generics.params,
1075+
&TraitBoundModifiers {
1076+
constness: BoundConstness::Never,
1077+
asyncness: BoundAsyncness::Normal,
1078+
polarity: match ai.of_trait.polarity {
1079+
ImplPolarity::Positive => BoundPolarity::Positive,
1080+
ImplPolarity::Negative(span) => BoundPolarity::Negative(span),
1081+
},
1082+
},
1083+
&ai.of_trait.trait_ref,
1084+
ai.of_trait.trait_ref.path.span,
1085+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
1086+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1087+
)),
1088+
&[],
1089+
),
1090+
false,
1091+
)
1092+
}
1093+
AssocItemKind::ExternImpl(..) => unreachable!("we should never lower ast::ExternImpl"),
10311094
AssocItemKind::Type(box TyAlias {
10321095
ident,
10331096
generics,
@@ -1233,6 +1296,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
12331296
),
12341297
)
12351298
}
1299+
AssocItemKind::AutoImpl(_) | AssocItemKind::ExternImpl(_) => {
1300+
feature_err(
1301+
&self.tcx.sess,
1302+
sym::supertrait_auto_impl,
1303+
i.span,
1304+
"feature is under construction",
1305+
)
1306+
.emit();
1307+
FatalError.raise();
1308+
}
12361309
AssocItemKind::Delegation(box delegation) => {
12371310
let delegation_results = self.lower_delegation(delegation, i.id);
12381311
(

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
@@ -1421,6 +1421,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14211421
}
14221422
visit::walk_item(self, item);
14231423
}
1424+
1425+
ItemKind::AutoImpl(..) => {
1426+
self.dcx().emit_err(errors::AutoImplOutsideTraitOrImplTrait { span: item.span });
1427+
}
1428+
14241429
_ => visit::walk_item(self, item),
14251430
}
14261431

0 commit comments

Comments
 (0)